Atest klucza i identyfikatora

Magazyn kluczy zapewnia bezpieczniejsze miejsce do tworzenia, przechowywania i używania kluczy kryptograficznych w kontrolowany sposób. Gdy dostępna i używana jest pamięć masowa oparta na sprzęcie, materiał klucza jest lepiej zabezpieczony przed wydobyciem 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 masowej wspieranej sprzętowo. W Keymaster 1 nie było możliwości, aby aplikacje lub serwery zdalne mogły wiarygodnie zweryfikować, czy tak jest. Demon magazynu kluczy załadował dostępny kluczowy HAL i uwierzył we wszystko, co powiedział HAL w odniesieniu do sprzętowego tworzenia kopii zapasowych kluczy.

Aby temu zaradzić, Keymaster wprowadziłatestację kluczy w systemie Android 7.0 (Keymaster 2) oraz atestację identyfikatorów w systemie Android 8.0 (Keymaster 3).

Atestacja klucza ma na celu zapewnienie sposobu na silne określenie, czy asymetryczna para kluczy jest obsługiwana sprzętowo, jakie są właściwości klucza i jakie ograniczenia są stosowane do jego użycia.

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

Kluczowe poświadczenie

Aby obsługiwać zaświadczanie kluczy, system Android 7.1 wprowadził zestaw tagów, typu i metody do warstwy HAL.

Tagi

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

Rodzaj

Keymaster 2 i poniżej

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

Metoda AttestKey

Keymaster 3

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

Keymaster 2 i poniżej

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 keymaster.
  • keyToAttest to obiekt BLOB klucza zwrócony z generateKey , dla którego zostanie utworzone zaświadczenie.
  • attestParams to lista wszystkich parametrów niezbędnych do atestacji. Obejmuje to Tag::ATTESTATION_CHALLENGE ::ATTESTATION_CHALLENGE i prawdopodobnie 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 jest certyfikatem atestacji, co oznacza, że ​​poświadcza klucz z keyToAttest i zawiera rozszerzenie atestacji.

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 atestowany klucz wymaga uwierzytelnienia użytkownika, zaświadczenie można wygenerować bez uwierzytelnienia użytkownika.

Certyfikat atestu

Certyfikat atestacyjny to standardowy certyfikat X.509 z opcjonalnym rozszerzeniem atestacyjnym zawierającym opis atestowanego klucza. Certyfikat jest podpisany fabrycznie dostarczonym kluczem atestacyjnym, który wykorzystuje ten sam algorytm, co atestowany klucz (RSA dla RSA, EC dla EC).

Certyfikat atestacji 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 zawartość certyfikatu jest dokładnie taka, jak zdefiniowano.

SEKWENCJA certyfikatu

Nazwa pola (patrz RFC 5280 ) Wartość
tbsCertyfikat TBSCertyfikat SEKWENCJA
podpisAlgorytm AlgorithmIdentifier algorytmu używanego do podpisywania 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.

TBSCertyfikat SEKWENCJA

Nazwa pola (patrz RFC 5280 ) Wartość
version INTEGER 2 (oznacza certyfikat v3)
serialNumber INTEGER 1 (wartość stała: taka sama na wszystkich certyfikatach)
signature AlgorithmIdentyfikator algorytmu używanego do podpisywania klucza: ECDSA dla kluczy EC, RSA dla kluczy RSA.
issuer To samo, co pole tematu w kluczu poświadczania partii.
validity SEKWENCJA dwóch dat, zawierająca wartości Tag::ACTIVE_DATETIME i Tag::USAGE_EXPIRE_DATETIME . Wartości te są podawane w milisekundach od 1 stycznia 1970 r. Zobacz RFC 5280 , aby uzyskać prawidłowe reprezentacje dat w certyfikatach.
Jeśli Tag::ACTIVE_DATETIME nie jest obecny, użyj wartości Tag::CREATION_DATETIME . Jeśli Tag::USAGE_EXPIRE_DATETIME nie istnieje, użyj daty ważności certyfikatu klucza poświadczania partii.
subject CN = "klucz Android Keystore" (wartość stała: taka sama we wszystkich certyfikatach)
subjectPublicKeyInfo SubjectPublicKeyInfo zawierający atestowany klucz publiczny.
extensions/Key Usage digitalSignature: ustaw, jeśli klucz ma przeznaczenie KeyPurpose::SIGN lub KeyPurpose::VERIFY . Wszystkie inne bity nieustawione.
extensions/CRL Distribution Points Wartość TBD
extensions/"attestation" OID to 1.3.6.1.4.1.11129.2.1.17; treść jest zdefiniowana w sekcji Rozszerzenie atestu poniżej. Podobnie jak w przypadku wszystkich rozszerzeń certyfikatów X.509, zawartość jest reprezentowana jako OCTET_STRING zawierający kodowanie DER atestacji SEQUENCE.

Rozszerzenie atestu

Rozszerzenie attestation zawiera pełny opis autoryzacji keymastera powiązanych z kluczem w strukturze, która bezpośrednio odpowiada listom autoryzacji używanym w systemie Android i keymasterowi HAL. Każdy znacznik na liście autoryzacji jest reprezentowany przez wpis ASN.1 SEQUENCE , wyraźnie oznaczony numerem znacznika keymastera, 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 poświadczenia wartość ENUM_REP jest usuwana, pozostawiając znacznik 1 . (W przypadku Keymaster 2 i starszych, KM_TAG_PURPOSE jest zdefiniowany w pliku 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 ZESTAW INTEGER
UINT LICZBA CAŁKOWITA
UINT_REP ZESTAW INTEGER
ULONG LICZBA CAŁKOWITA
ULONG_REP ZESTAW INTEGER
DATE INTEGER (milisekundy od 1 stycznia 1970 00:00:00 GMT)
BOOL NULL (w keymasterze tag obecny oznacza prawdę, nieobecny oznacza fałsz.
Ta sama semantyka dotyczy kodowania ASN.1)
BIGNUM Obecnie nie jest używany, więc mapowanie nie jest zdefiniowane
BYTES OCTET_STRING

Schemat

Zawartość rozszerzenia atestacji 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 oznaczone 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 zaświadczenia. Możliwe jest uzyskanie atestów oprogramowania kluczy wspieranych sprzętowo. Takim zaświadczeniom 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 keymastera.
attestationChallenge OCTET_STRING Wartość Tag::ATTESTATION_CHALLENGE , określona w żądaniu atestacji.
uniqueId OCTET_STRING Opcjonalny unikalny identyfikator, obecny, jeśli klucz ma Tag::INCLUDE_UNIQUE_ID
softwareEnforced Lista autoryzacji Opcjonalne autoryzacje administratora, które nie są wymuszane przez TEE, jeśli takie istnieją.
teeEnforced Lista autoryzacji Opcjonalne autoryzacje Keymastera, które są egzekwowane 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 tagowanie jawne, więc pola zawierają również tag 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 poniżej. Nazwy znaczników Keymaster zostały przekształcone w nazwy pól przez pominięcie prefiksu KM_TAG i zmianę reszty na wielkość wielbłąda, 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żywany do weryfikacji obrazu systemu. Zalecany SHA-256.
deviceLocked BOOLEAN Prawda, jeśli bootloader jest zablokowany, co oznacza, że ​​można flashować tylko podpisane obrazy i przeprowadza się zweryfikowane sprawdzanie rozruchu.
verifiedBootState Zweryfikowany stan rozruchowy Stan sprawdzonego rozruchu.
verifiedBootHash OCTET_STRING Zestawienie wszystkich danych chronionych przez Verified Boot. W przypadku urządzeń korzystających z implementacji Verified Boot w systemie 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

Zweryfikowane wartości BootState

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

Wartość Oznaczający
Verified Wskazuje pełny łańcuch zaufania rozciągający się od bootloadera do zweryfikowanych partycji, w tym bootloadera, partycji rozruchowej i wszystkich zweryfikowanych partycji.
W tym stanie wartość verifiedBootKey jest hashem wbudowanego certyfikatu, co oznacza niezmienny certyfikat wypalony w pamięci ROM.
SelfSigned Wskazuje, że partycja rozruchowa została zweryfikowana przy użyciu wbudowanego certyfikatu, a podpis jest ważny. Bootloader wyświetla ostrzeżenie i odcisk palca klucza publicznego przed umożliwieniem kontynuowania procesu rozruchu.
W tym stanie wartość verifiedBootKey jest skrótem certyfikatu samopodpisującego.
Unverified Wskazuje, że urządzenie można dowolnie modyfikować. Integralność urządzenia pozostawia się użytkownikowi do weryfikacji poza pasmem. Program ładujący wyświetla ostrzeżenie dla użytkownika przed zezwoleniem na kontynuację procesu rozruchu.
W tym stanie wartość verifiedBootKey jest pusta.
Failed Wskazuje, że weryfikacja urządzenia nie powiodła się. Żaden certyfikat atestacyjny nie zawiera tej wartości, ponieważ w tym stanie bootloader zatrzymuje się. Zawarto tutaj dla kompletności.

Wartości poziomu bezpieczeństwa

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

Wartość Oznaczający
Software Kod, który tworzy lub zarządza odpowiednim elementem (zaświadczeniem lub kluczem) jest zaimplementowany w systemie Android i może zostać zmieniony w przypadku naruszenia bezpieczeństwa tego systemu.
TrustedEnvironment Kod, który tworzy lub zarządza odpowiednim elementem (zaświadczeniem lub kluczem) jest implementowany w Trusted Execution Environment (TEE). Może to ulec zmianie, jeśli TEE zostanie naruszony, ale TEE jest wysoce odporny na zdalne włamanie i umiarkowanie odporny na włamanie przez bezpośredni atak sprzętowy.
StrongBox Kod, który tworzy lub zarządza odpowiednim elementem (atestem lub kluczem) jest zaimplementowany w dedykowanym module zabezpieczeń sprzętowych. Może zostać zmieniony, jeśli sprzętowy moduł bezpieczeństwa zostanie naruszony, ale jest wysoce odporny na zdalne włamanie i wysoce odporny na włamanie przez bezpośredni atak sprzętowy.

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, odrzucając resztę. 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 jest unikalnym sekretem sprzętowym, znanym Trusted Execution Environment i nigdy przez nie ujawnionym. Sekret zawiera co najmniej 128 bitów entropii i jest unikalny dla pojedynczego urządzenia (jednoznaczność probabilistyczna jest dopuszczalna, biorąc pod uwagę 128 bitów entropii). HBK powinien pochodzić z połączonego materiału klucza 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 udostępniane w urządzeniu.

Poświadczenie 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 przedstawienie dowodu 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 pozwala na większe bezpieczeństwo w przypadkach użycia, takich jak prawdziwa zdalna konfiguracja bezdotykowa (ponieważ strona zdalna może być tego pewna mówi do właściwego urządzenia, a nie do podszywania się pod jego tożsamość).

Zaświadczanie identyfikatorów 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 oraz zmienić oprogramowanie systemowe i identyfikatory raportowane przez frameworki Android. Kopiami identyfikatorów przechowywanymi przez TEE nie można manipulować w ten sposób, co zapewnia, że ​​poświadczenie identyfikatora urządzenia będzie zawsze potwierdzać oryginalne identyfikatory sprzętowe urządzenia, zapobiegając w ten sposób próbom fałszowania.

Główna powierzchnia interfejsu API do poświadczania identyfikatorów opiera się na istniejącym mechanizmie poświadczania kluczy wprowadzonym w Keymaster 2. Podczas żądania certyfikatu poświadczającego dla klucza przechowywanego przez Keymaster osoba wywołująca może zażądać, aby identyfikatory sprzętowe urządzenia zostały uwzględnione w metadanych certyfikatu poświadczającego. Jeśli klucz jest przechowywany w TEE, certyfikat powróci do znanego źródła zaufania. Odbiorca takiego certyfikatu może zweryfikować, czy certyfikat i jego zawartość, w tym identyfikatory sprzętu, zostały napisane przez TEE. Poproszony o uwzględnienie identyfikatorów sprzętowych w certyfikacie atestacyjnym, TEE atestuje tylko identyfikatory przechowywane w jego magazynie, zgodnie z wypełnieniem 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, zanim urządzenie opuści fabrykę.
  • Metoda destroyAttestationIds() może trwale zniszczyć tę kopię danych pochodzących z identyfikatora. Trwałe zniszczenie oznacza, że ​​dane są całkowicie usuwane, 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 Android.
  • Obiekty 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ć atestację ID. Mechanizm używany przez obiekty RMA musi być chroniony, aby użytkownicy nie mogli sami się z niego wywoływać, ponieważ pozwoliłoby im to na uzyskanie zaświadczeń o sfałszowanych identyfikatorach.
  • Żaden kod inny niż zaufana aplikacja Keymaster w TEE nie jest w stanie odczytać danych pochodzących z identyfikatora przechowywanych w pamięci.
  • Miejsce przechowywania jest zabezpieczone przed manipulacją: jeśli zawartość magazynu została zmodyfikowana, TEE traktuje ją tak samo, jak gdyby kopie zawartości zostały zniszczone, i odrzuca wszystkie próby poświadczenia tożsamości. Jest to realizowane poprzez podpisanie lub MACowanie pamięci , jak opisano poniżej .
  • Magazyn nie zawiera oryginalnych identyfikatorów. Ponieważ zaświadczanie identyfikatorów wiąże się z wyzwaniem, osoba wywołująca zawsze dostarcza identyfikatory, które mają być zaświadczane. TEE musi jedynie zweryfikować, czy odpowiadają one pierwotnie posiadanym wartościom. Przechowywanie bezpiecznych skrótów oryginalnych wartości, a nie wartości, umożliwia tę weryfikację.

Budowa

Aby utworzyć implementację o właściwościach wymienionych powyżej, przechowuj wartości pochodzące od identyfikatora w następującej konstrukcji S. Nie przechowuj innych kopii wartości identyfikatora, 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 hashem (zalecany SHA-256)
  • HBK to klucz sprzętowy, 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óżne liczby identyfikatorów
  • || reprezentuje konkatenację

Ponieważ dane wyjściowe HMAC mają stały rozmiar, nie są wymagane żadne nagłówki ani inna struktura, aby można było znaleźć poszczególne skróty identyfikatorów lub HMAC z D. Oprócz sprawdzania dostarczonych wartości w celu przeprowadzenia atestacji, implementacje muszą sprawdzać S, wyodrębniając D z S , obliczając HMAC(HBK, D) i porównując go z wartością w S w celu sprawdzenia, czy żadne indywidualne identyfikatory nie zostały zmodyfikowane/uszkodzone. Ponadto implementacje muszą używać porównań w czasie stałym dla wszystkich poszczególnych elementów identyfikatorów i walidacji 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

Atest ID obsługuje następujące identyfikatory sprzętu:

  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. Numery IMEI wszystkich radiotelefonów
  8. MEID wszystkich radiotelefonów

Aby obsługiwać zaświadczanie identyfikatora urządzenia, urządzenie potwierdza 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 zintegrowane radiotelefony komórkowe, musi również obsługiwać atest dla IMEI i/lub MEID radiotelefonów.

Poświadczenie identyfikatora jest wymagane przez wykonanie poświadczenia klucza i uwzględnienie w żądaniu identyfikatorów urządzeń do poświadczenia. 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 zakodowany w UTF-8 ciąg bajtów. 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() , a 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, kończy się niepowodzeniem z ErrorCode::CANNOT_ATTEST_IDS .

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

W przypadku pomyślnej atestacji, certyfikowane identyfikatory są dodawane do rozszerzenia atestacji (OID 1.3.6.1.4.1.11129.2.1.17) wystawionego certyfikatu atestacyjnego, korzystając ze schematu z powyższego . Zmiany ze schematu atestacji Keymaster 2 są pogrubione , z komentarzami.

API Javy

Ta sekcja ma charakter wyłącznie informacyjny. Realizatorzy Keymaster nie implementują ani nie używają Java API. Jest to udostępniane, aby pomóc realizatorom zrozumieć, w jaki sposób funkcja jest używana przez aplikacje. Komponenty systemu mogą z niego korzystać w różny sposób, dlatego ważne jest, aby ten rozdział nie był traktowany jako normatywny.