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 zgenerateKey
, dla którego zostanie utworzone zaświadczenie. -
attestParams
to lista wszystkich parametrów niezbędnych do atestacji. Obejmuje toTag::ATTESTATION_CHALLENGE
::ATTESTATION_CHALLENGE i prawdopodobnieTag::RESET_SINCE_ID_ROTATION
, a takżeTag::APPLICATION_ID
iTag::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 zkeyToAttest
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ściTag::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śliTag::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:
- Nazwa marki zwrócona przez
Build.BRAND
w systemie Android - Nazwa urządzenia zwrócona przez
Build.DEVICE
w systemie Android - Nazwa produktu zwrócona przez
Build.PRODUCT
w systemie Android - Nazwa producenta zwrócona przez
Build.MANUFACTURER
w systemie Android - Nazwa modelu zwrócona przez
Build.MODEL
w systemie Android - Numer seryjny
- Numery IMEI wszystkich radiotelefonów
- 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.