Poświadczenie klucza i dowodu osobistego

Magazyn kluczy zapewnia bezpieczniejsze miejsce do tworzenia, przechowywania i używania kluczy kryptograficznych w kontrolowany sposób. Gdy dostępne i używane jest sprzętowe przechowywanie kluczy, materiał klucza jest bezpieczniejszy przed wyodrębnieniem z urządzenia, a Keymaster wymusza ograniczenia, które są trudne do obejścia.

Jest to jednak prawdą tylko wtedy, gdy wiadomo, że klucze magazynu kluczy znajdują się w pamięci sprzętowej. W Keymaster 1 aplikacje lub zdalne serwery nie mogły wiarygodnie zweryfikować, czy tak jest. Demon magazynu kluczy załadował dostępną bazę kluczy HAL i uwierzył we wszystko, co HAL powiedziała w odniesieniu do sprzętowego wsparcia kluczy.

Aby temu zaradzić, Keymaster wprowadził poświadczenie klucza w systemie Android 7.0 (Keymaster 2) i poświadczenie identyfikatora w systemie Android 8.0 (Keymaster 3).

Zaświadczenie klucza ma na celu zapewnienie sposobu na dokładne określenie, czy asymetryczna para kluczy jest wspierana sprzętowo, jakie są właściwości klucza i jakie ograniczenia są stosowane w jego użyciu.

Zaświadczenie ID pozwala urządzeniu przedstawić dowód swoich identyfikatorów sprzętowych, takich jak numer seryjny lub IMEI.

Kluczowe świadectwo

Aby obsługiwać zaświadczanie kluczy, w systemie Android 7.1 wprowadzono zestaw znaczników, typów i metod do warstwy HAL.

Tagi

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

Typ

Keymaster 2 i starsze

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

Metoda AttestKey

Klucznik 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 i starsze

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev to struktura urządzenia głównego klucza.
  • keyToAttest to kluczowy obiekt blob zwrócony z generateKey , dla którego zostanie utworzone zaświadczenie.
  • attestParams to lista wszelkich parametrów niezbędnych do zaświadczenia. Obejmuje to Tag::ATTESTATION_CHALLENGE i ewentualnie Tag::RESET_SINCE_ID_ROTATION , a także Tag::APPLICATION_ID i Tag::APPLICATION_DATA . Te dwa ostatnie są niezbędne do odszyfrowania obiektu blob klucza, jeśli zostały określone podczas generowania klucza.
  • certChain jest parametrem wyjściowym, który zwraca tablicę certyfikatów. Wpis 0 jest certyfikatem atestacyjnym, co oznacza, że ​​poświadcza klucz z keyToAttest i zawiera rozszerzenie atestu.

Metoda attestKey jest uważana za operację klucza publicznego na certyfikowanym kluczu, ponieważ można ją wywołać w dowolnym momencie i nie musi spełniać ograniczeń autoryzacyjnych. Na przykład, jeśli zaświadczony klucz wymaga uwierzytelnienia użytkownika, zaświadczenie można wygenerować bez uwierzytelniania użytkownika.

Certyfikat atestu

Certyfikat zaświadczający to standardowy certyfikat X.509 z opcjonalnym rozszerzeniem zaświadczającym, które zawiera opis atestowanego klucza. Certyfikat jest podpisany certyfikowanym kluczem atestacyjnym . Klucz poświadczający może wykorzystywać inny algorytm niż klucz poświadczany.

Certyfikat atestu zawiera pola z poniższej tabeli i nie może zawierać żadnych dodatkowych pól. Niektóre pola określają stałą wartość pola. Testy CTS potwierdzają, że zawartość certyfikatu jest dokładnie taka, jak zdefiniowano.

SEKWENCJA Certyfikatu

Nazwa pola (patrz RFC 5280 ) Wartość
tbsCertyfikat SEKWENCJA certyfikatu TBS
algorytm podpisu AlgorithmIdentifier algorytmu użytego do podpisania klucza:
ECDSA dla kluczy EC, RSA dla kluczy RSA.
Wartość podpisu BIT STRING, podpis obliczony na podstawie certyfikatu tbsCertificate zakodowanego w formacie ASN.1 DER.

SEKWENCJA certyfikatu TBS

Nazwa pola (patrz RFC 5280 ) Wartość
version INTEGER 2 (oznacza certyfikat v3)
serialNumber INTEGER 1 (stała wartość: taka sama dla wszystkich certyfikatów)
signature AlgorytmIdentyfikator algorytmu użytego do podpisywania klucza: ECDSA dla kluczy EC, RSA dla kluczy RSA.
issuer Takie samo jak pole tematu klucza zaświadczenia partii.
validity SEKWENCJA dwóch dat, zawierająca wartości Tag::ACTIVE_DATETIME i Tag::USAGE_EXPIRE_DATETIME . Wartości te podano w milisekundach od 1 stycznia 1970 r. Prawidłowe przedstawienie daty w certyfikatach można znaleźć w dokumencie RFC 5280 .
Jeśli Tag::ACTIVE_DATETIME nie jest obecny, użyj wartości Tag::CREATION_DATETIME . Jeśli Tag::USAGE_EXPIRE_DATETIME nie jest obecny, użyj daty wygaśnięcia certyfikatu klucza zaświadczenia partii.
subject CN = „Klucz magazynu kluczy Androida” (stała wartość: taka sama dla wszystkich certyfikatów)
subjectPublicKeyInfo TematPublicKeyInfo zawierający poświadczony klucz publiczny.
extensions/Key Usage digitalSignature: ustaw, jeśli klucz ma cel KeyPurpose::SIGN lub KeyPurpose::VERIFY . Wszystkie pozostałe bity są nieustawione.
extensions/CRL Distribution Points Wartość do ustalenia
extensions/"attestation" Identyfikator OID to 1.3.6.1.4.1.11129.2.1.17; treść jest zdefiniowana w poniższej sekcji „Przedłużenie zaświadczenia”. Podobnie jak w przypadku wszystkich rozszerzeń certyfikatów X.509, treść jest reprezentowana jako OCTET_STRING zawierający kodowanie DER SEQUENCE zaświadczenia.

Przedłużenie atestu

Rozszerzenie attestation zawiera pełny opis uprawnień keymastera powiązanych z kluczem, w strukturze bezpośrednio odpowiadającej listom autoryzacji używanym w systemie Android i keymaster HAL. Każdy znacznik na liście autoryzacji jest reprezentowany przez wpis ASN.1 SEQUENCE , wyraźnie oznaczony numerem znacznika klucza głównego, ale z zamaskowanym deskryptorem typu (cztery bity wyższego rzędu).

Na przykład w Keymaster 3 Tag::PURPOSE jest zdefiniowany w types.hal jako ENUM_REP | 1 . W przypadku rozszerzenia zaświadczenia wartość ENUM_REP jest usuwana, pozostawiając znacznik 1 . (W przypadku Keymaster 2 i starszych, KM_TAG_PURPOSE jest zdefiniowany w keymaster_defs.h.)

Wartości są tłumaczone w prosty sposób na typy ASN.1, zgodnie z poniższą tabelą:

Typ Keymastera Typ ASN.1
ENUM LICZBA CAŁKOWITA
ENUM_REP ZBIÓR LICZBY CAŁKOWITEJ
UINT LICZBA CAŁKOWITA
UINT_REP ZBIÓR LICZBY CAŁKOWITEJ
ULONG LICZBA CAŁKOWITA
ULONG_REP ZBIÓR LICZBY CAŁKOWITEJ
DATE INTEGER (milisekundy od 1 stycznia 1970 r. 00:00:00 GMT)
BOOL NULL (w kluczu, znacznik obecny oznacza prawdę, brak oznacza fałsz.
Ta sama semantyka dotyczy kodowania ASN.1)
BIGNUM Nie jest obecnie używany, więc nie zdefiniowano żadnego mapowania
BYTES OCTET_STRING

Schemat

Treść rozszerzenia atestu opisana jest następującym schematem ASN.1.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

Pola opisu klucza

Pola keymasterVersion i attestationChallenge są identyfikowane pozycyjnie, a nie według znacznika, zatem znaczniki w zakodowanej formie określają jedynie typ pola. Pozostałe pola są domyślnie oznakowane zgodnie ze schematem.

Nazwa pola Typ Wartość
attestationVersion LICZBA CAŁKOWITA Wersja schematu atestacji: 1, 2 lub 3.
attestationSecurity Poziom bezpieczeństwa Poziom bezpieczeństwa tego zaświadczenia. Istnieje możliwość uzyskania atestów programowych kluczy sprzętowych. Takim atestom nie można ufać, jeśli system Android zostanie naruszony.
keymasterVersion LICZBA CAŁKOWITA Wersja urządzenia keymaster: 0, 1, 2, 3 lub 4.
keymasterSecurity Poziom bezpieczeństwa Poziom bezpieczeństwa implementacji klucza głównego.
attestationChallenge OCTET_STRING Wartość Tag::ATTESTATION_CHALLENGE określona dla żądania zaświadczenia.
uniqueId OCTET_STRING Opcjonalny unikalny identyfikator, obecny, jeśli klucz ma Tag::INCLUDE_UNIQUE_ID
softwareEnforced Lista autoryzacji Opcjonalne, autoryzacje keymastera, które nie są egzekwowane przez TEE, jeśli takie istnieją.
teeEnforced Lista autoryzacji Opcjonalne, autoryzacje Keymaster wymuszane przez TEE, jeśli istnieją.

Pola listy autoryzacji

Wszystkie pola AuthorizationList są opcjonalne i są identyfikowane na podstawie wartości znacznika klucza głównego, z zamaskowanymi bitami typu. Stosowane jest jawne tagowanie, więc pola zawierają również znacznik wskazujący ich typ ASN.1, w celu łatwiejszego analizowania.

Aby uzyskać szczegółowe informacje na temat wartości każdego pola, zobacz types.hal dla Keymaster 3 i keymaster_defs.h dla Keymaster 2 i niższych. Nazwy tagów Keymaster zostały przekształcone w nazwy pól poprzez pominięcie przedrostka KM_TAG i zmianę pozostałej części na wielkie litery, więc Tag::KEY_SIZE stał się keySize .

Pola RootOfTrust

Pola RootOfTrust są identyfikowane pozycyjnie.

Nazwa pola Typ Wartość
verifiedBootKey OCTET_STRING Bezpieczny skrót klucza używany do weryfikacji obrazu systemu. Zalecany SHA-256.
deviceLocked BOOLEAN Prawda, jeśli program ładujący jest zablokowany, co oznacza, że ​​można flashować tylko podpisane obrazy i że przeprowadzono zweryfikowane sprawdzanie rozruchu.
verifiedBootState Zweryfikowany stan rozruchu Stan zweryfikowanego rozruchu.
verifiedBootHash OCTET_STRING Podsumowanie wszystkich danych chronionych przez Verified Boot. W przypadku urządzeń korzystających z implementacji Verified Boot systemu Android Verified Boot ta wartość zawiera skrót struktury VBMeta lub struktury metadanych Verified Boot. Aby dowiedzieć się więcej o tym, jak obliczyć tę wartość, zobaczPodsumowanie VBMeta

Wartości VerifiedBootState

Wartości verifiedBootState mają następujące znaczenie:

Wartość Oznaczający
Verified Wskazuje pełny łańcuch zaufania rozciągający się od programu ładującego do zweryfikowanych partycji, w tym programu ładującego, partycji rozruchowej i wszystkich zweryfikowanych partycji.
W tym stanie wartość verifiedBootKey jest skrótem wbudowanego certyfikatu, co oznacza niezmienny certyfikat wypalony w pamięci ROM.
Ten stan odpowiada zielonemu stanowi rozruchu udokumentowanemu w zweryfikowanej dokumentacji przepływu rozruchu .
SelfSigned Wskazuje, że partycja rozruchowa została zweryfikowana przy użyciu wbudowanego certyfikatu, a podpis jest ważny. Program ładujący wyświetla ostrzeżenie i odcisk palca klucza publicznego, zanim umożliwi kontynuację procesu rozruchu.
W tym stanie wartość verifiedBootKey jest skrótem certyfikatu z podpisem własnym.
Ten stan odpowiada żółtemu stanowi rozruchu, jak udokumentowano w zweryfikowanej dokumentacji przepływu rozruchu .
Unverified Wskazuje, że urządzenie można dowolnie modyfikować. Weryfikację integralności urządzenia poza pasmem pozostawia się użytkownikowi. Program ładujący wyświetla użytkownikowi ostrzeżenie przed zezwoleniem na kontynuację procesu rozruchu.
W tym stanie wartość verifiedBootKey jest pusta.
Ten stan odpowiada pomarańczowemu stanowi rozruchu, jak udokumentowano w zweryfikowanej dokumentacji przepływu rozruchu .
Failed Wskazuje, że weryfikacja urządzenia nie powiodła się. Żaden certyfikat atestujący tak naprawdę nie zawiera tej wartości, ponieważ w tym stanie program ładujący zatrzymuje się. Jest tu uwzględniony dla kompletności.
Ten stan odpowiada czerwonemu stanowi rozruchu, jak udokumentowano w zweryfikowanej dokumentacji przepływu rozruchu .

Wartości poziomu zabezpieczeń

Wartości securityLevel mają następujące znaczenie:

Wartość Oznaczający
Software Kod, który tworzy odpowiedni element (zaświadczenie lub klucz) lub zarządza nim, jest zaimplementowany w systemie Android i może zostać zmieniony w przypadku naruszenia bezpieczeństwa tego systemu.
TrustedEnvironment Kod tworzący odpowiedni element (certyfikat lub klucz) lub zarządzający nim jest zaimplementowany w zaufanym środowisku wykonawczym (TEE). Można to zmienić, jeśli TEE zostanie naruszone, ale TEE jest wysoce odporny na zdalne naruszenie i umiarkowanie odporny na kompromis w wyniku bezpośredniego ataku sprzętowego.
StrongBox Kod tworzący lub zarządzający odpowiednim elementem (atestem lub kluczem) zaimplementowany jest w dedykowanym sprzętowym module bezpieczeństwa. Można go zmienić, jeśli sprzętowy moduł zabezpieczeń zostanie naruszony, ale jest on wysoce odporny na zdalne ataki i bardzo odporny na bezpośrednie ataki sprzętowe.

Unikalny identyfikator

Unikalny identyfikator to 128-bitowa wartość identyfikująca urządzenie, ale tylko przez ograniczony czas. Wartość jest obliczana za pomocą:

HMAC_SHA256(T || C || R, HBK)

Gdzie:

  • T to „tymczasowa wartość licznika” obliczona poprzez podzielenie wartości Tag::CREATION_DATETIME przez 2592000000, pomijając resztę. T zmienia się co 30 dni (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C jest wartością Tag::APPLICATION_ID
  • R wynosi 1, jeśli Tag::RESET_SINCE_ID_ROTATION jest obecny w parametrze attest_params wywołania attest_key, lub 0, jeśli znacznik nie jest obecny.
  • HBK to unikalny sekret związany ze sprzętem, znany zaufanemu środowisku wykonawczemu i nigdy przez nie ujawniany. Sekret zawiera co najmniej 128 bitów entropii i jest unikalny dla konkretnego urządzenia (dopuszczalna jest unikalność probabilistyczna, biorąc pod uwagę 128 bitów entropii). HBK powinien pochodzić z materiału klucza skondensowanego za pośrednictwem HMAC lub AES_CMAC.

Skróć dane wyjściowe HMAC_SHA256 do 128 bitów.

Klucze atestacyjne i certyfikaty

Dwa klucze, jeden RSA i jeden ECDSA, oraz odpowiednie łańcuchy certyfikatów są bezpiecznie dostarczane do urządzenia.

W systemie Android 12 wprowadzono zdalne udostępnianie kluczy, a w systemie Android 13 wymagane jest wdrożenie tej funkcji przez urządzenia. Usługa Remote Key Provisioning zapewnia urządzeniom terenowym certyfikaty ECDSA P256 dla poszczególnych aplikacji. Certyfikaty te są krótsze niż certyfikaty dostarczane fabrycznie.

Wiele numerów IMEI

W systemie Android 14 dodano obsługę wielu numerów IMEI w rekordzie zaświadczenia klucza systemu Android. Producenci OEM mogą wdrożyć tę funkcję, dodając znacznik KeyMint dla drugiego numeru IMEI. Coraz powszechniejsze staje się wyposażenie urządzeń w wiele radiotelefonów komórkowych, a producenci OEM mogą teraz obsługiwać urządzenia z dwoma numerami IMEI.

Producenci OEM są zobowiązani do posiadania dodatkowego numeru IMEI, jeśli jest on obecny na ich urządzeniach, w celu zapewnienia implementacji KeyMint, aby te implementacje mogły to potwierdzić w taki sam sposób, w jaki potwierdzają pierwszy IMEI

Poświadczenie tożsamości

Android 8.0 zawiera opcjonalną obsługę poświadczenia tożsamości dla urządzeń z Keymaster 3. Poświadczenie tożsamości pozwala urządzeniu przedstawić dowód jego identyfikatorów sprzętowych, takich jak numer seryjny lub IMEI. Mimo że jest to funkcja opcjonalna, zdecydowanie zaleca się, aby wszystkie implementacje Keymaster 3 zapewniały jej obsługę, ponieważ możliwość potwierdzenia tożsamości urządzenia sprawia, że ​​przypadki użycia, takie jak prawdziwa zdalna konfiguracja typu zero-touch, są bezpieczniejsze (ponieważ strona zdalna może być pewna, że komunikuje się z właściwym urządzeniem, a nie z urządzeniem podszywającym się pod jego tożsamość).

Zaświadczenie identyfikatora polega na utworzeniu kopii identyfikatorów sprzętowych urządzenia, do których dostęp ma wyłącznie zaufane środowisko wykonawcze (TEE), zanim urządzenie opuści fabrykę. Użytkownik może odblokować bootloader urządzenia oraz zmienić oprogramowanie systemowe i identyfikatory raportowane przez frameworki Android. Kopiami identyfikatorów przechowywanych przez TEE nie można manipulować w ten sposób, co gwarantuje, że poświadczenie identyfikatora urządzenia będzie zawsze potwierdzać jedynie oryginalne identyfikatory sprzętowe urządzenia, co udaremni próby fałszerstwa.

Główna powierzchnia API służąca do zaświadczania identyfikatorów opiera się na istniejącym mechanizmie zaświadczania kluczy wprowadzonym w Keymaster 2. Żądając certyfikatu zaświadczającego dla klucza posiadanego przez keymastera, osoba wywołująca może zażądać uwzględnienia identyfikatorów sprzętowych urządzenia w metadanych certyfikatu zaświadczającego. Jeśli klucz jest przechowywany w TEE, certyfikat zostanie powiązany ze znanym źródłem zaufania. Odbiorca takiego certyfikatu może sprawdzić, czy certyfikat i jego zawartość, w tym identyfikatory sprzętowe, zostały napisane przez TEE. Poproszony o uwzględnienie identyfikatorów sprzętu w certyfikacie atestacyjnym, TEE poświadcza wyłącznie identyfikatory przechowywane w jej magazynie, zgodnie z ich obecnością w hali produkcyjnej.

Właściwości przechowywania

Pamięć przechowująca identyfikatory urządzenia musi mieć następujące właściwości:

  • Wartości pochodzące z oryginalnych identyfikatorów urządzenia są kopiowane do pamięci przed opuszczeniem przez urządzenie fabryki.
  • MetodazniszczAttestationIds destroyAttestationIds() może trwale zniszczyć tę kopię danych pochodzących z identyfikatora. Trwałe zniszczenie oznacza, że ​​dane zostaną całkowicie usunięte i ani przywrócenie ustawień fabrycznych, ani żadna inna procedura wykonana na urządzeniu nie będzie w stanie ich przywrócić. Jest to szczególnie ważne w przypadku urządzeń, na których użytkownik odblokował bootloader i zmienił oprogramowanie systemowe oraz zmodyfikował identyfikatory zwracane przez frameworki Android.
  • Placówki RMA powinny mieć możliwość generowania świeżych kopii danych pochodzących z identyfikatora sprzętu. W ten sposób urządzenie, które przejdzie przez RMA, będzie mogło ponownie przeprowadzić atest identyfikacyjny. Mechanizm stosowany przez placówki RMA musi być chroniony, aby użytkownicy nie mogli się na niego samodzielnie powołać, gdyż umożliwiłoby to im uzyskanie poświadczeń sfałszowanych dokumentów tożsamości.
  • Żaden kod inny niż zaufana aplikacja Keymaster w TEE nie jest w stanie odczytać danych pochodzących z identyfikatora przechowywanych w pamięci.
  • Pamięć jest zabezpieczona przed manipulacją: jeżeli zawartość pamięci została zmodyfikowana, TEE traktuje ją tak samo, jak gdyby kopie zawartości zostały zniszczone i odrzuca wszelkie próby poświadczenia tożsamości. Jest to realizowane poprzez podpisanie lub MACowanie pamięci , jak opisano poniżej .
  • W magazynie nie są przechowywane oryginalne identyfikatory. Ponieważ poświadczenie tożsamości wiąże się z wyzwaniem, osoba dzwoniąca zawsze dostarcza identyfikatory, które mają zostać poświadczone. TEE musi jedynie sprawdzić, czy odpowiadają one pierwotnym wartościom. Przechowywanie bezpiecznych skrótów oryginalnych wartości zamiast wartości umożliwia tę weryfikację.

Budowa

Aby utworzyć implementację posiadającą wymienione powyżej właściwości, zapisz wartości pochodzące z identyfikatora w następującej konstrukcji S. Nie przechowuj innych kopii wartości identyfikatorów, z wyjątkiem normalnych miejsc w systemie, które właściciel urządzenia może modyfikować poprzez rootowanie:

S = D || HMAC(HBK, D)

Gdzie:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC to konstrukcja HMAC z odpowiednim bezpiecznym skrótem (zalecane SHA-256)
  • HBK jest kluczem sprzętowym, który nie jest używany do żadnego innego celu
  • ID 1 ...ID n to oryginalne wartości ID; powiązanie określonej wartości z określonym indeksem zależy od implementacji, ponieważ różne urządzenia będą miały różną liczbę identyfikatorów
  • || reprezentuje konkatenację

Ponieważ dane wyjściowe HMAC mają stały rozmiar, nie są wymagane żadne nagłówki ani inna struktura, aby móc znaleźć indywidualne skróty identyfikatorów lub HMAC D. Oprócz sprawdzania dostarczonych wartości w celu przeprowadzenia atestu, implementacje muszą zweryfikować S poprzez wyodrębnienie D z S , obliczając HMAC(HBK, D) i porównując go z wartością w S, aby sprawdzić, czy żaden indywidualny identyfikator nie został zmodyfikowany/uszkodzony. Ponadto implementacje muszą wykorzystywać porównania w stałym czasie dla wszystkich poszczególnych elementów identyfikatora i walidację S. Czas porównania musi być stały niezależnie od liczby dostarczonych identyfikatorów i prawidłowego dopasowania dowolnej części testu.

Identyfikatory sprzętu

Zaświadczenie ID obsługuje następujące identyfikatory sprzętowe:

  1. Nazwa marki zwrócona przez Build.BRAND w systemie Android
  2. Nazwa urządzenia zwrócona przez Build.DEVICE w systemie Android
  3. Nazwa produktu zwrócona przez Build.PRODUCT w systemie Android
  4. Nazwa producenta zwrócona przez Build.MANUFACTURER w systemie Android
  5. Nazwa modelu zwrócona przez Build.MODEL w systemie Android
  6. Numer seryjny
  7. IMEI wszystkich radiotelefonów
  8. MEID wszystkich radiotelefonów

Aby umożliwić zaświadczenie identyfikatora urządzenia, urządzenie potwierdza te identyfikatory. Wszystkie urządzenia z Androidem mają pierwsze sześć i są one niezbędne, aby ta funkcja działała. Jeśli urządzenie jest wyposażone w zintegrowane radiotelefony komórkowe, musi także obsługiwać atest dla numerów IMEI i/lub MEID radiotelefonów.

Żądanie potwierdzenia tożsamości polega na wykonaniu zaświadczenia klucza i dołączeniu identyfikatorów urządzenia w celu poświadczenia w żądaniu. Identyfikatory są oznaczone jako:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

Identyfikator do poświadczenia to ciąg bajtów zakodowany w formacie UTF-8. Ten format dotyczy również identyfikatorów numerycznych. Każdy identyfikator do poświadczenia jest wyrażony jako ciąg znaków zakodowany w formacie UTF-8.

Jeśli urządzenie nie obsługuje zaświadczania identyfikatorów (lub wcześniej wywołano destroyAttestationIds() i urządzenie nie może już zatwierdzić swoich identyfikatorów), każde żądanie zaświadczenia klucza zawierające jeden lub więcej z tych znaczników kończy się niepowodzeniem z ErrorCode::CANNOT_ATTEST_IDS .

Jeżeli urządzenie obsługuje poświadczenie identyfikatora i co najmniej jeden z powyższych znaczników został uwzględniony w żądaniu zaświadczenia klucza, TEE weryfikuje, czy identyfikator dostarczony z każdym ze znaczników jest zgodny z jego kopią identyfikatorów sprzętowych. Jeśli jeden lub więcej identyfikatorów nie jest zgodnych, całe zaświadczenie kończy się niepowodzeniem z błędem ErrorCode::CANNOT_ATTEST_IDS . Dopuszczalne jest wielokrotne dostarczenie tego samego tagu. Może to być przydatne na przykład podczas sprawdzania numerów IMEI: urządzenie może być wyposażone w wiele radiotelefonów z wieloma numerami IMEI. Żądanie zaświadczenia jest ważne, jeśli wartość podana w każdym ATTESTATION_ID_IMEI odpowiada jednemu z radiotelefonów urządzenia. To samo dotyczy wszystkich innych tagów.

Jeżeli atestacja przebiegnie pomyślnie, atestowane identyfikatory dodawane są do rozszerzenia atestu (OID 1.3.6.1.4.1.11129.2.1.17) wystawionego certyfikatu atestacyjnego, korzystając ze schematu jak powyżej . Zmiany w schemacie atestacji Keymaster 2 są pogrubione i zawierają komentarze.

API Javy

Ta sekcja ma charakter wyłącznie informacyjny. Osoby wdrażające Keymaster nie implementują ani nie używają interfejsu API języka Java. Ma to na celu pomóc wdrażającym zrozumieć, w jaki sposób ta funkcja jest wykorzystywana przez aplikacje. Komponenty systemu mogą z niego korzystać w różny sposób, dlatego tak ważne jest, aby tej sekcji nie traktować jako normatywnej.