Atest klucza i identyfikatora

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

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

Jest to jednak prawdą tylko wtedy, gdy wiadomo, że klucze magazynu kluczy znajdują się w magazynie wspieranym sprzętowo. W Keymaster 1 nie było sposobu, aby aplikacje lub serwery zdalne niezawodnie sprawdziły, czy tak jest. Demon magazynu kluczy załadował dostępny główny klucz HAL i uwierzył we wszystko, co powiedział HAL w odniesieniu do sprzętowego zabezpieczenia kluczy.

Aby temu zaradzić, firma Keymaster wprowadziłapoświadczenie klucza w systemie Android 7.0 (Keymaster 2) oraz poświadczenie tożsamości w systemie Android 8.0 (Keymaster 3).

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

Zaświadczenie ID umożliwia urządzeniu potwierdzenie jego identyfikatorów sprzętowych, takich jak numer seryjny lub IMEI.

Atest klucza

Aby obsługiwać atestację klucza, system Android 7.1 wprowadził zestaw tagów, typów i metod do warstwy HAL.

Tagi

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

Rodzaj

Keymaster 2 i niższe

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 niższe

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 jest obiektem blob klucza zwróconym 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 ::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 to parametr wyjściowy, który zwraca tablicę certyfikatów. Wpis 0 to certyfikat poświadczający, co oznacza, że ​​poświadcza klucz z keyToAttest i zawiera rozszerzenie poświadczające.

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

Świadectwo atestacyjne

Certyfikat poświadczający jest standardowym certyfikatem X.509 z opcjonalnym rozszerzeniem poświadczającym, które zawiera opis poświadczonego klucza. Certyfikat jest podpisany fabrycznie dostarczonym kluczem poświadczającym, który wykorzystuje ten sam algorytm, co uwierzytelniany klucz (RSA dla RSA, EC dla EC).

Certyfikat poświadczający 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 sprawdzają, czy treść certyfikatu jest dokładnie taka, jak zdefiniowano.

SEKWENCJA certyfikatu

Nazwa pola (patrz RFC 5280 ) Wartość
tbsCertyfikat SEKWENCJA certyfikatu TBS
podpisAlgorytm AlgorithmIdentifier algorytmu użytego do podpisania klucza:
ECDSA dla kluczy EC, RSA dla kluczy RSA.
wartość podpisu ŁAŃCUCH BITÓW, podpis obliczony na zakodowanym w ASN.1 DER tbsCertificate.

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 AlgorithmIdentyfikator algorytmu użytego do podpisania klucza: ECDSA dla kluczy EC, RSA dla kluczy RSA.
issuer To samo, co pole tematu klucza poświadczenia partii.
validity SEKWENCJA dwóch dat, zawierająca wartości Tag::ACTIVE_DATETIME i Tag::USAGE_EXPIRE_DATETIME . Wartości te są wyrażone w milisekundach od 1 stycznia 1970 r. Prawidłowe przedstawianie dat 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 systemu Android” (stała wartość: taka sama dla wszystkich certyfikatów)
subjectPublicKeyInfo SubjectPublicKeyInfo 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" OID to 1.3.6.1.4.1.11129.2.1.17; treść jest zdefiniowana w sekcji Rozszerzenie zaświadczenia poniżej. Podobnie jak w przypadku wszystkich rozszerzeń certyfikatu X.509, treść jest reprezentowana jako OCTET_STRING zawierający kodowanie DER SEKWENCJI poświadczenia.

Rozszerzenie atestu

Rozszerzenie attestation zawiera pełny opis autoryzacji klucza głównego powiązanych z kluczem, w strukturze, która bezpośrednio odpowiada listom autoryzacji używanym w systemie Android i HAL klucza głównego. Każdy znacznik na liście autoryzacji jest reprezentowany przez wpis SEQUENCE ASN.1, wyraźnie oznaczony numerem znacznika głównego klucza, 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 . (Dla Keymaster 2 i 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 klucza typ ASN.1
ENUM LICZBA CAŁKOWITA
ENUM_REP ZBIÓR LICZB CAŁKOWITYCH
UINT LICZBA CAŁKOWITA
UINT_REP ZBIÓR LICZB CAŁKOWITYCH
ULONG LICZBA CAŁKOWITA
ULONG_REP ZBIÓR LICZB CAŁKOWITYCH
DATE INTEGER (milisekundy od 1 stycznia 1970 00:00:00 GMT)
BOOL NULL (w keymaster, tag obecny oznacza prawdę, nieobecny oznacza fałsz.
Ta sama semantyka dotyczy kodowania ASN.1)
BIGNUM Nie jest obecnie używany, więc nie zdefiniowano mapowania
BYTES OCTET_STRING

Schemat

Zawartość rozszerzenia zaświadczenia jest opisana w następującym schemacie 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 KeyDescription

Pola keymasterVersion i attestationChallenge są identyfikowane pozycyjnie, a nie według tagów, więc tagi w zakodowanej formie określają tylko typ pola. Pozostałe pola są niejawnie oznakowane zgodnie ze schematem.

Nazwa pola Rodzaj Wartość
attestationVersion LICZBA CAŁKOWITA Wersja schematu atestacji: 1, 2 lub 3.
attestationSecurity Poziom bezpieczeństwa Poziom bezpieczeństwa tego poświadczenia. Możliwe jest uzyskanie atestów programowych kluczy wspieranych sprzętowo. 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 w żądaniu zaświadczenia.
uniqueId OCTET_STRING Opcjonalny unikalny identyfikator, obecny, jeśli klucz ma Tag::INCLUDE_UNIQUE_ID
softwareEnforced Lista autoryzacji Opcjonalne autoryzacje administratora klucza, które nie są wymuszane przez TEE, jeśli takie istnieją.
teeEnforced Lista autoryzacji Opcjonalne autoryzacje Keymaster, które są wymuszane przez TEE, jeśli takie istnieją.

Pola listy autoryzacji

Wszystkie pola AuthorizationList są opcjonalne i są identyfikowane przez wartość znacznika keymaster z zamaskowanymi bitami typu. Stosowane jest jawne tagowanie, więc pola zawierają również znacznik wskazujący ich typ ASN.1, co ułatwia analizę.

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 przez pominięcie przedrostka KM_TAG i zmianę reszty na wielbłąd, więc Tag::KEY_SIZE stał się keySize .

Pola RootOfTrust

Pola RootOfTrust są identyfikowane pozycyjnie.

Nazwa pola Rodzaj Wartość
verifiedBootKey OCTET_STRING Bezpieczny skrót klucza używanego do weryfikacji obrazu systemu. Zalecane SHA-256.
deviceLocked BOOLEAN Prawda, jeśli program ładujący jest zablokowany, co oznacza, że ​​można flashować tylko podpisane obrazy i przeprowadzane jest 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 ta wartość zawiera skrót struktury VBMeta lub struktury metadanych Verified Boot. Aby dowiedzieć się więcej o tym, jak obliczyć tę wartość, zobacz The VBMeta Digest

VerifiedBootState wartości

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, jak udokumentowano w dokumentacji zweryfikowanego 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 przed zezwoleniem na kontynuowanie procesu rozruchu.
W tym stanie wartość verifiedBootKey jest skrótem certyfikatu z podpisem własnym.
Ten stan odpowiada żółtemu stanowi rozruchu zgodnie z dokumentacją zweryfikowanego przepływu rozruchu .
Unverified Wskazuje, że urządzenie można dowolnie modyfikować. Użytkownik może zweryfikować integralność urządzenia poza pasmem. Program ładujący wyświetla użytkownikowi ostrzeżenie przed zezwoleniem na kontynuowanie procesu rozruchu.
W tym stanie wartość verifiedBootKey jest pusta.
Ten stan odpowiada pomarańczowemu stanowi rozruchu zgodnie z dokumentacją zweryfikowanego przepływu rozruchu .
Failed Wskazuje, że weryfikacja urządzenia nie powiodła się. Żaden certyfikat poświadczający faktycznie nie zawiera tej wartości, ponieważ w tym stanie program ładujący zatrzymuje się. Jest to zawarte tutaj dla kompletności.
Ten stan odpowiada czerwonemu stanowi rozruchu zgodnie z dokumentacją zweryfikowanego przepływu rozruchu .

wartości SecurityLevel

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

Wartość Oznaczający
Software Kod, który tworzy odpowiedni element (poś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, który tworzy odpowiedni element (poświadczenie lub klucz) lub zarządza nim, jest implementowany w Trusted Execution Environment (TEE). Może zostać zmieniony, jeśli TEE zostanie naruszony, ale TEE jest wysoce odporny na zdalne naruszenie i umiarkowanie odporny na naruszenie przez bezpośredni atak sprzętowy.
StrongBox Kod tworzący lub zarządzający odpowiednim elementem (poświadczeniem lub kluczem) jest zaimplementowany w dedykowanym sprzętowym module bezpieczeństwa. Może zostać zmieniony, jeśli sprzętowy moduł bezpieczeństwa zostanie naruszony, ale jest wysoce odporny na zdalne ataki i wysoce odporny na bezpośrednie ataki sprzętowe.

Unikalny identyfikator

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

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

Gdzie:

  • T jest „czasową wartością licznika”, obliczoną przez podzielenie wartości Tag::CREATION_DATETIME przez 2592000000, z pominięciem reszty. T zmienia się co 30 dni (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C to wartość 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 tag nie jest obecny.
  • HBK to unikalny klucz związany ze sprzętem, znany Trusted Execution Environment i nigdy przez niego nie ujawniany. Sekret zawiera co najmniej 128 bitów entropii i jest unikalny dla danego urządzenia (niepowtarzalność probabilistyczna jest akceptowalna, biorąc pod uwagę 128 bitów entropii). HBK powinien pochodzić z materiału z kluczem skondensowanym przez 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 odpowiadające im łańcuchy certyfikatów są bezpiecznie dostarczane do urządzenia.

zaświadczenie o tożsamości

Android 8.0 zawiera opcjonalną obsługę poświadczania tożsamości dla urządzeń z Keymaster 3. Poświadczanie tożsamości umożliwia urządzeniu potwierdzenie jego identyfikatorów sprzętowych, takich jak numer seryjny lub IMEI. Chociaż jest to funkcja opcjonalna, zdecydowanie zaleca się, aby wszystkie implementacje Keymaster 3 zapewniały jej obsługę, ponieważ możliwość udowodnienia tożsamości urządzenia umożliwia większe bezpieczeństwo przypadków użycia, takich jak zdalna konfiguracja bezdotykowa (ponieważ strona zdalna może być pewna, że rozmawia z właściwym urządzeniem, a nie z urządzeniem podszywającym się pod jego tożsamość).

Poświadczanie tożsamości polega na tworzeniu kopii identyfikatorów sprzętowych urządzenia, do których dostęp ma tylko Trusted Execution Environment (TEE), zanim urządzenie opuści fabrykę. Użytkownik może odblokować bootloader urządzenia i zmienić oprogramowanie systemowe oraz identyfikatory zgłaszane przez frameworki Androida. Kopiami identyfikatorów przechowywanych przez TEE nie można manipulować w ten sposób, zapewniając, że zaświadczenie o identyfikatorze urządzenia będzie zawsze potwierdzać tylko oryginalne identyfikatory sprzętowe urządzenia, udaremniając w ten sposób próby fałszowania.

Główna powierzchnia API do poświadczania identyfikatorów opiera się na istniejącym mechanizmie poświadczania klucza wprowadzonym w Keymaster 2. Żądając certyfikatu poświadczającego dla klucza posiadanego przez keymaster, dzwoniący może zażądać uwzględnienia identyfikatorów sprzętowych urządzenia w metadanych certyfikatu poświadczającego. Jeśli klucz jest przechowywany w TEE, certyfikat zostanie połączony z powrotem do znanego źródła zaufania. Odbiorca takiego certyfikatu może zweryfikować, czy certyfikat i jego zawartość, w tym identyfikatory sprzętowe, zostały napisane przez TEE. Poproszony o umieszczenie identyfikatorów sprzętu w certyfikacie, TEE poświadcza tylko identyfikatory przechowywane w jego pamięci, wypełnione na hali produkcyjnej.

Właściwości przechowywania

Magazyn przechowujący identyfikatory urządzenia musi mieć te właściwości:

  • Wartości pochodzące z oryginalnych identyfikatorów urządzenia są kopiowane do pamięci, zanim urządzenie opuści fabrykę.
  • Metoda destroyAttestationIds() może trwale zniszczyć tę kopię danych pochodzących z identyfikatora. Trwałe zniszczenie oznacza całkowite usunięcie danych, więc ani przywrócenie ustawień fabrycznych, ani żadna inna procedura wykonana na urządzeniu nie może 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 Androida.
  • Placówki RMA powinny mieć możliwość generowania nowych kopii danych pochodzących z identyfikatora sprzętu. W ten sposób urządzenie, które przejdzie przez RMA, może ponownie przeprowadzić poświadczenie tożsamości. Mechanizm używany przez placówki RMA musi być chroniony, aby użytkownicy nie mogli się na niego powoływać, ponieważ pozwoliłoby im to na uzyskanie poświadczeń sfałszowanych identyfikatorów.
  • Żaden kod inny niż zaufana aplikacja Keymaster w TEE nie jest w stanie odczytać danych pochodzących z identyfikatora przechowywanych w pamięci.
  • Przechowywanie jest zabezpieczone przed manipulacją: jeśli zawartość magazynu została zmodyfikowana, TEE traktuje to tak samo, jak gdyby kopie treści zostały zniszczone i odrzuca wszelkie próby potwierdzenia tożsamości. Jest to realizowane przez podpisywanie lub adresowanie MAC magazynu , jak opisano poniżej .
  • Magazyn nie przechowuje oryginalnych identyfikatorów. Ponieważ poświadczenie tożsamości wiąże się z wyzwaniem, dzwoniący zawsze podaje identyfikatory do poświadczenia. TEE musi jedynie zweryfikować, czy odpowiadają one wartościom, które pierwotnie miały. Przechowywanie bezpiecznych skrótów oryginalnych wartości zamiast wartości umożliwia tę weryfikację.

Budowa

Aby utworzyć implementację, która ma wymienione powyżej właściwości, przechowuj wartości pochodne ID w następującej konstrukcji S. Nie przechowuj innych kopii wartości ID, z wyjątkiem normalnych miejsc w systemie, które właściciel urządzenia może modyfikować przez 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 (zalecany SHA-256)
  • HBK to klucz związany ze sprzętem, który nie jest używany do żadnych innych celów
  • ID 1 ...ID n to oryginalne wartości ID; powiązanie określonej wartości z określonym indeksem jest zależne 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źć skróty poszczególnych identyfikatorów lub HMAC D. Oprócz sprawdzania dostarczonych wartości w celu przeprowadzenia atestacji, 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 żadne indywidualne identyfikatory nie zostały zmodyfikowane/uszkodzone. Ponadto implementacje muszą wykorzystywać porównania w czasie stałym dla wszystkich poszczególnych elementów ID oraz 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

Poświadczenie ID obsługuje następujące identyfikatory sprzętu:

  1. Nazwa marki zwrócona przez Build.BRAND w Androidzie
  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 Androidzie
  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 obsługiwać poświadczanie identyfikatorów urządzeń, urządzenie poświadcza te identyfikatory. Wszystkie urządzenia z systemem Android mają pierwsze sześć i są one niezbędne do działania tej funkcji. Jeśli urządzenie ma wbudowane radiotelefony komórkowe, musi ono również obsługiwać poświadczanie numerów IMEI i/lub MEID radiotelefonów.

Zaświadczenie ID jest wymagane przez wykonanie zaświadczenia klucza i podanie identyfikatorów urządzeń do zaś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 zakodowany w UTF-8.

Jeśli urządzenie nie obsługuje poświadczania identyfikatorów (lub destroyAttestationIds() i urządzenie nie może już poświadczać swoich identyfikatorów), każde żądanie poświadczenia klucza, które zawiera co najmniej jeden z tych tagów, zakończy się niepowodzeniem z błędem ErrorCode::CANNOT_ATTEST_IDS .

Jeśli urządzenie obsługuje poświadczanie tożsamości, a żądanie poświadczenia klucza zawiera co najmniej jeden z powyższych znaczników, TEE weryfikuje, czy identyfikator dostarczony z każdym ze znaczników jest zgodny z jego kopią identyfikatorów sprzętu. Jeśli jeden lub więcej identyfikatorów nie pasuje, całe zaświadczenie kończy się niepowodzeniem z ErrorCode::CANNOT_ATTEST_IDS . Dozwolone jest wielokrotne podanie tego samego tagu. Może to być przydatne na przykład podczas potwierdzania numerów IMEI: Urządzenie może mieć wiele radiotelefonów z wieloma numerami IMEI. Żądanie zaświadczenia jest ważne, jeśli wartość podana z każdym ATTESTATION_ID_IMEI jest zgodna z jednym z urządzeń radiowych urządzenia. To samo dotyczy wszystkich innych tagów.

Jeśli poświadczenie zakończy się pomyślnie, poświadczone identyfikatory zostaną dodane do rozszerzenia poświadczenia (OID 1.3.6.1.4.1.11129.2.1.17) wystawionego poświadczenia, korzystając ze schematu z powyższego . Zmiany w stosunku do schematu atestacji Keymaster 2 są pogrubione i opatrzone komentarzami.

API Javy

Ta sekcja ma charakter wyłącznie informacyjny. Implementatorzy Keymaster nie implementują ani nie używają API Java. Ma to na celu ułatwienie implementatorom zrozumienia, w jaki sposób ta funkcja jest używana przez aplikacje. Komponenty systemu mogą wykorzystywać go w różny sposób, dlatego ważne jest, aby ten rozdział nie był traktowany jako normatywny.