Schlüssel- und ID-Beglaubigung

Keystore bietet einen sichereren Ort zum kontrollierten Erstellen, Speichern und Verwenden von kryptografischen Schlüsseln. Wenn ein hardwaregestützter Schlüsselspeicher verfügbar ist und verwendet wird, ist das Schlüsselmaterial sicherer gegen die Extraktion aus dem Gerät, und Keymaster erzwingt Beschränkungen, die schwer zu umgehen sind.

Dies gilt jedoch nur, wenn bekannt ist, dass sich die Keystore-Schlüssel in einem hardwaregestützten Speicher befinden. In Keymaster 1 gab es keine Möglichkeit für Apps oder Remote-Server, zuverlässig zu überprüfen, ob dies der Fall war. Der Keystore-Daemon lud die verfügbare Keymaster-HAL und glaubte, was auch immer die HAL in Bezug auf die Hardware-Unterstützung von Schlüsseln sagte.

Um dies zu beheben, hat Keymasterdie Schlüsselbeglaubigung in Android 7.0 (Keymaster 2) und die ID-Beglaubigung in Android 8.0 (Keymaster 3) eingeführt.

Der Schlüsselnachweis zielt darauf ab, eine Möglichkeit zu bieten, um sicher zu bestimmen, ob ein asymmetrisches Schlüsselpaar hardwaregestützt ist, welche Eigenschaften der Schlüssel hat und welche Einschränkungen auf seine Verwendung angewendet werden.

Die ID-Bestätigung ermöglicht es dem Gerät, seine Hardwarekennungen wie Seriennummer oder IMEI nachzuweisen.

Schlüsselbescheinigung

Um den Schlüsselnachweis zu unterstützen, hat Android 7.1 eine Reihe von Tags, Typen und Methoden in die HAL eingeführt.

Stichworte

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

Typ

Keymaster 2 und darunter

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

AttestKey -Methode

Schlüsselmeister 3

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

Keymaster 2 und darunter

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 ist die Keymaster-Gerätestruktur.
  • keyToAttest ist das Schlüsselblob, das von generateKey zurückgegeben wird, für das die Beglaubigung erstellt wird.
  • attestParams ist eine Liste aller für die Beglaubigung erforderlichen Parameter. Dazu gehören Tag::ATTESTATION_CHALLENGE und möglicherweise Tag::RESET_SINCE_ID_ROTATION sowie Tag::APPLICATION_ID und Tag::APPLICATION_DATA . Die beiden letzteren sind zum Entschlüsseln des Schlüsselblobs erforderlich, wenn sie während der Schlüsselgenerierung angegeben wurden.
  • certChain ist der Ausgabeparameter, der ein Array von Zertifikaten zurückgibt. Eintrag 0 ist das Beglaubigungszertifikat, d. h. es beglaubigt den Schlüssel von keyToAttest und enthält die Beglaubigungserweiterung.

Die attestKey Methode wird als Public-Key-Operation für den attestierten Schlüssel betrachtet, da sie jederzeit aufgerufen werden kann und keine Autorisierungsbeschränkungen erfüllen muss. Wenn zum Beispiel der attestierte Schlüssel zur Verwendung eine Benutzerauthentifizierung benötigt, kann eine Attestierung ohne Benutzerauthentifizierung generiert werden.

Beglaubigungszertifikat

Das Beglaubigungszertifikat ist ein standardmäßiges X.509-Zertifikat mit einer optionalen Beglaubigungserweiterung, die eine Beschreibung des beglaubigten Schlüssels enthält. Das Zertifikat wird mit einem zertifizierten Beglaubigungsschlüssel signiert. Der Beglaubigungsschlüssel kann einen anderen Algorithmus verwenden als der zu beglaubigende Schlüssel.

Das Beglaubigungszertifikat enthält die Felder in der folgenden Tabelle und darf keine zusätzlichen Felder enthalten. Einige Felder geben einen festen Feldwert an. CTS-Tests validieren, dass der Zertifikatsinhalt genau wie definiert ist.

Zertifikat SEQUENZ

Feldname (siehe RFC 5280 ) Wert
tbsZertifikat TBSCertificate SEQUENZ
Signaturalgorithm AlgorithmIdentifier des Algorithmus, der zum Signieren des Schlüssels verwendet wird:
ECDSA für EC-Schlüssel, RSA für RSA-Schlüssel.
Signaturwert BIT STRING, Signatur berechnet auf ASN.1 DER-codiertem tbsCertificate.

TBSCertificate SEQUENZ

Feldname (siehe RFC 5280 ) Wert
version INTEGER 2 (bedeutet v3-Zertifikat)
serialNumber INTEGER 1 (fester Wert: auf allen Zertifikaten gleich)
signature AlgorithmusBezeichner des zum Signieren des Schlüssels verwendeten Algorithmus: ECDSA für EC-Schlüssel, RSA für RSA-Schlüssel.
issuer Entspricht dem Betrefffeld des Batch-Beglaubigungsschlüssels.
validity SEQUENCE von zwei Daten, die die Werte von Tag::ACTIVE_DATETIME und Tag::USAGE_EXPIRE_DATETIME enthalten. Diese Werte sind in Millisekunden seit dem 1. Januar 1970 angegeben. Siehe RFC 5280 für korrekte Datumsdarstellungen in Zertifikaten.
Wenn Tag::ACTIVE_DATETIME nicht vorhanden ist, verwenden Sie den Wert von Tag::CREATION_DATETIME . Wenn Tag::USAGE_EXPIRE_DATETIME nicht vorhanden ist, verwenden Sie das Ablaufdatum des Schlüsselzertifikats für die Stapelbeglaubigung.
subject CN = "Android Keystore Key" (fester Wert: auf allen Zertifikaten gleich)
subjectPublicKeyInfo SubjectPublicKeyInfo, das den attestierten öffentlichen Schlüssel enthält.
extensions/Key Usage digitalSignature: gesetzt, wenn der Schlüssel einen Zweck hat KeyPurpose::SIGN oder KeyPurpose::VERIFY . Alle anderen Bits nicht gesetzt.
extensions/CRL Distribution Points Wert offen
extensions/"attestation" Die OID ist 1.3.6.1.4.1.11129.2.1.17; der Inhalt wird im Abschnitt Attestation Extension weiter unten definiert. Wie bei allen X.509-Zertifikatserweiterungen wird der Inhalt als OCTET_STRING dargestellt, der eine DER-Codierung der Beglaubigung SEQUENCE enthält.

Bescheinigungserweiterung

Die attestation enthält eine vollständige Beschreibung der dem Schlüssel zugeordneten Keymaster-Berechtigungen in einer Struktur, die direkt den Berechtigungslisten entspricht, wie sie in Android und der Keymaster-HAL verwendet werden. Jedes Tag in einer Autorisierungsliste wird durch einen ASN.1 SEQUENCE Eintrag dargestellt, der explizit mit der Keymaster-Tag-Nummer gekennzeichnet ist, aber mit dem Typdeskriptor (vier höherwertige Bits) maskiert ist.

Beispielsweise ist in Keymaster 3 Tag::PURPOSE in types.hal als ENUM_REP | 1 definiert ENUM_REP | 1 . Für die Beglaubigungserweiterung wird der Wert ENUM_REP entfernt, sodass Tag 1 übrig bleibt. (Für Keymaster 2 und darunter ist KM_TAG_PURPOSE in keymaster_defs.h definiert.)

Werte werden gemäß dieser Tabelle auf einfache Weise in ASN.1-Typen übersetzt:

Keymaster-Typ Typ ASN.1
ENUM GANZE ZAHL
ENUM_REP SET von INTEGER
UINT GANZE ZAHL
UINT_REP SET von INTEGER
ULONG GANZE ZAHL
ULONG_REP SET von INTEGER
DATE INTEGER (Millisekunden seit dem 1. Januar 1970 00:00:00 GMT)
BOOL NULL (in Keymaster bedeutet Tag vorhanden wahr, abwesend bedeutet falsch.
Dieselbe Semantik gilt für die ASN.1-Codierung)
BIGNUM Derzeit nicht verwendet, daher ist keine Zuordnung definiert
BYTES OCTET_STRING

Schema

Der Inhalt der Beglaubigungserweiterung wird durch das folgende ASN.1-Schema beschrieben.

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),
}

KeyDescription-Felder

Die Felder keymasterVersion und attestationChallenge werden nach Position und nicht nach Tags identifiziert, sodass die Tags in der codierten Form nur den Feldtyp angeben. Die restlichen Felder werden implizit wie im Schema angegeben getaggt.

Feldname Typ Wert
attestationVersion GANZE ZAHL Version des Attestierungsschemas: 1, 2 oder 3.
attestationSecurity Sicherheitsstufe Die Sicherheitsstufe dieser Bescheinigung. Es ist möglich, Softwarebescheinigungen von hardwaregestützten Schlüsseln zu erhalten. Solchen Bescheinigungen kann nicht vertraut werden, wenn das Android-System kompromittiert ist.
keymasterVersion GANZE ZAHL Version des Keymaster-Geräts: 0, 1, 2, 3 oder 4.
keymasterSecurity Sicherheitsstufe Die Sicherheitsstufe der Keymaster-Implementierung.
attestationChallenge OCTET_STRING Wert von Tag::ATTESTATION_CHALLENGE , angegeben für die Beglaubigungsanforderung.
uniqueId OCTET_STRING Optionale eindeutige ID, vorhanden, wenn Schlüssel Tag::INCLUDE_UNIQUE_ID hat
softwareEnforced Autorisierungsliste Optionale Keymaster-Autorisierungen, die nicht vom TEE erzwungen werden, falls vorhanden.
teeEnforced Autorisierungsliste Optionale Keymaster-Autorisierungen, die ggf. vom TEE erzwungen werden.

AuthorizationList-Felder

AuthorizationList Felder sind alle optional und werden durch den Keymaster-Tag-Wert identifiziert, wobei die Typbits maskiert sind. Es wird explizites Tagging verwendet, sodass die Felder zur einfacheren Analyse auch ein Tag enthalten, das ihren ASN.1-Typ angibt.

Einzelheiten zu den Werten der einzelnen Felder finden Sie types.hal für Keymaster 3 und keymaster_defs.h für Keymaster 2 und darunter. Keymaster-Tag-Namen wurden in Feldnamen umgewandelt, indem das Präfix KM_TAG weggelassen und der Rest in Kamelschreibweise geändert wurde, sodass Tag::KEY_SIZE zu keySize wurde.

RootOfTrust-Felder

Die RootOfTrust Felder werden positionsbezogen identifiziert.

Feldname Typ Wert
verifiedBootKey OCTET_STRING Ein sicherer Hash des Schlüssels, der zum Verifizieren des Systemabbilds verwendet wird. SHA-256 empfohlen.
deviceLocked BOOLEAN True, wenn der Bootloader gesperrt ist, was bedeutet, dass nur signierte Images geflasht werden können und dass eine verifizierte Boot-Überprüfung durchgeführt wird.
verifiedBootState Verifizierter BootState Status des verifizierten Starts.
verifiedBootHash OCTET_STRING Eine Zusammenfassung aller Daten, die durch Verified Boot geschützt sind. Für Geräte, die die Android Verified Boot-Implementierung von Verified Boot verwenden, enthält dieser Wert den Digest der VBMeta-Struktur oder die Verified Boot-Metadatenstruktur. Weitere Informationen zur Berechnung dieses Werts finden Sie unter The VBMeta Digest

VerifiedBootState-Werte

Die Werte verifiedBootState haben folgende Bedeutung:

Wert Bedeutung
Verified Zeigt eine vollständige Vertrauenskette an, die sich vom Bootloader bis zu verifizierten Partitionen erstreckt, einschließlich des Bootloaders, der Bootpartition und aller verifizierten Partitionen.
In diesem Zustand ist der verifiedBootKey Wert der Hash des eingebetteten Zertifikats, d. h. das unveränderliche Zertifikat, das in das ROM eingebrannt ist.
Dieser Zustand entspricht dem grünen Boot-Zustand, wie er in der verifizierten Boot-Flow -Dokumentation dokumentiert ist.
SelfSigned Zeigt an, dass die Startpartition mit dem eingebetteten Zertifikat verifiziert wurde und die Signatur gültig ist. Der Bootloader zeigt eine Warnung und den Fingerabdruck des öffentlichen Schlüssels an, bevor der Bootvorgang fortgesetzt werden kann.
In diesem Zustand ist der verifiedBootKey Wert der Hash des selbstsignierenden Zertifikats.
Dieser Zustand entspricht dem gelben Boot-Zustand, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.
Unverified Zeigt an, dass ein Gerät frei modifiziert werden kann. Die Überprüfung der Geräteintegrität bleibt dem Benutzer überlassen. Der Bootloader zeigt dem Benutzer eine Warnung an, bevor der Startvorgang fortgesetzt werden kann.
In diesem Zustand ist der verifiedBootKey Wert leer.
Dieser Zustand entspricht dem orangefarbenen Boot-Zustand, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.
Failed Zeigt an, dass die Überprüfung des Geräts fehlgeschlagen ist. Kein Beglaubigungszertifikat enthält tatsächlich diesen Wert, da der Bootloader in diesem Zustand anhält. Es ist hier der Vollständigkeit halber enthalten.
Dieser Zustand entspricht dem roten Boot-Zustand, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.

SecurityLevel-Werte

Die Werte von securityLevel haben folgende Bedeutung:

Wert Bedeutung
Software Der Code, der das relevante Element (Bestätigung oder Schlüssel) erstellt oder verwaltet, ist im Android-System implementiert und könnte geändert werden, wenn dieses System kompromittiert wird.
TrustedEnvironment Der Code, der das relevante Element (Attestierung oder Schlüssel) erstellt oder verwaltet, wird in einer Trusted Execution Environment (TEE) implementiert. Es könnte geändert werden, wenn das TEE kompromittiert wird, aber das TEE ist sehr widerstandsfähig gegenüber einer Kompromittierung aus der Ferne und mäßig widerstandsfähig gegenüber einer Beeinträchtigung durch einen direkten Hardwareangriff.
StrongBox Der Code, der das relevante Element (Bestätigung oder Schlüssel) erstellt oder verwaltet, wird in einem dedizierten Hardware-Sicherheitsmodul implementiert. Es könnte geändert werden, wenn das Hardware-Sicherheitsmodul kompromittiert wird, aber es ist sehr widerstandsfähig gegen eine Kompromittierung aus der Ferne und sehr widerstandsfähig gegen eine Beeinträchtigung durch einen direkten Hardwareangriff.

Eindeutige ID

Die eindeutige ID ist ein 128-Bit-Wert, der das Gerät identifiziert, jedoch nur für einen begrenzten Zeitraum. Der Wert errechnet sich mit:

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

Wo:

  • T ist der "zeitliche Zählerwert", der berechnet wird, indem der Wert von Tag::CREATION_DATETIME durch 2592000000 geteilt wird, wobei alle Reste weggelassen werden. T ändert sich alle 30 Tage (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C ist der Wert von Tag::APPLICATION_ID
  • R ist 1, wenn Tag::RESET_SINCE_ID_ROTATION im attest_params-Parameter des attest_key-Aufrufs vorhanden ist, oder 0, wenn das Tag nicht vorhanden ist.
  • HBK ist ein einzigartiges hardwaregebundenes Geheimnis, das der Trusted Execution Environment bekannt ist und von ihr nie preisgegeben wird. Das Geheimnis enthält mindestens 128 Entropiebits und ist für das einzelne Gerät eindeutig (probabilistische Eindeutigkeit ist angesichts der 128 Entropiebits akzeptabel). HBK sollte aus verschmolzenem Schlüsselmaterial über HMAC oder AES_CMAC abgeleitet werden.

Kürzen Sie die HMAC_SHA256-Ausgabe auf 128 Bit.

Beglaubigungsschlüssel und Zertifikate

Zwei Schlüssel, ein RSA und ein ECDSA, und die entsprechenden Zertifikatsketten werden sicher im Gerät bereitgestellt.

Android 12 führt Remote Key Provisioning ein, und Android 13 erfordert, dass Geräte es implementieren. Remote Key Provisioning versorgt Geräte im Feld mit ECDSA P256-Bestätigungszertifikaten pro Anwendung. Diese Zertifikate haben eine kürzere Lebensdauer als die werkseitig bereitgestellten Zertifikate.

ID-Bescheinigung

Android 8.0 beinhaltet optionale Unterstützung für die ID-Bestätigung für Geräte mit Keymaster 3. Die ID-Bestätigung ermöglicht es dem Gerät, seine Hardwarekennungen wie Seriennummer oder IMEI nachzuweisen. Obwohl es sich um ein optionales Feature handelt, wird dringend empfohlen, dass alle Keymaster 3-Implementierungen es unterstützen, da die Möglichkeit, die Identität des Geräts nachzuweisen, Anwendungsfälle wie eine echte Zero-Touch-Remote-Konfiguration sicherer macht (weil die Remote-Seite sich dessen sicher sein kann spricht mit dem richtigen Gerät, nicht mit einem Gerät, das seine Identität vortäuscht).

Die ID-Bestätigung funktioniert, indem Kopien der Hardwarekennungen des Geräts erstellt werden, auf die nur die Trusted Execution Environment (TEE) zugreifen kann, bevor das Gerät das Werk verlässt. Ein Benutzer kann den Bootloader des Geräts entsperren und die Systemsoftware und die von den Android-Frameworks gemeldeten Kennungen ändern. Die Kopien der vom TEE gespeicherten Identifikatoren können auf diese Weise nicht manipuliert werden, wodurch sichergestellt wird, dass die Geräte-ID-Bestätigung immer nur die ursprünglichen Hardware-Identifikatoren des Geräts bestätigt, wodurch Spoofing-Versuche vereitelt werden.

Die Haupt-API-Oberfläche für die ID-Beglaubigung baut auf dem bestehenden Schlüsselbeglaubigungsmechanismus auf, der mit Keymaster 2 eingeführt wurde. Beim Anfordern eines Beglaubigungszertifikats für einen Schlüssel im Besitz von Keymaster kann der Aufrufer anfordern, dass die Hardwarekennungen des Geräts in die Metadaten des Beglaubigungszertifikats aufgenommen werden. Wenn der Schlüssel im TEE aufbewahrt wird, wird das Zertifikat zu einem bekannten Vertrauensanker zurückverkettet. Der Empfänger eines solchen Zertifikats kann verifizieren, dass das Zertifikat und sein Inhalt, einschließlich der Hardwarekennungen, von der TEE geschrieben wurden. Bei der Aufforderung, Hardwarekennungen in das Beglaubigungszertifikat aufzunehmen, attestiert das TEE nur die in seinem Speicher befindlichen Kennungen, wie sie in der Fabrikhalle vorhanden sind.

Speichereigenschaften

Der Speicher, der die Kennungen des Geräts enthält, muss diese Eigenschaften aufweisen:

  • Die aus den ursprünglichen Kennungen des Geräts abgeleiteten Werte werden in den Speicher kopiert, bevor das Gerät das Werk verlässt.
  • Die Methode destroyAttestationIds() kann diese Kopie der von der Kennung abgeleiteten Daten dauerhaft zerstören. Dauerhafte Zerstörung bedeutet, dass die Daten vollständig entfernt werden, sodass sie weder durch Zurücksetzen auf die Werkseinstellungen noch durch andere auf dem Gerät durchgeführte Verfahren wiederhergestellt werden können. Dies ist besonders wichtig für Geräte, bei denen ein Benutzer den Bootloader entsperrt und die Systemsoftware geändert und die von Android-Frameworks zurückgegebenen Kennungen geändert hat.
  • RMA-Einrichtungen sollten in der Lage sein, neue Kopien der von der Hardwarekennung abgeleiteten Daten zu erstellen. Auf diese Weise kann ein Gerät, das die RMA durchläuft, erneut eine ID-Beglaubigung durchführen. Der von RMA-Einrichtungen verwendete Mechanismus muss geschützt werden, damit Benutzer ihn nicht selbst aufrufen können, da dies es ihnen ermöglichen würde, Bescheinigungen über gefälschte IDs zu erhalten.
  • Kein anderer Code als die vertrauenswürdige Keymaster-App im TEE ist in der Lage, die von der Kennung abgeleiteten Daten im Speicher zu lesen.
  • Die Aufbewahrung ist manipulationssicher: Wenn der Inhalt der Aufbewahrung verändert wurde, behandelt das TEE dies so, als ob die Kopien der Inhalte vernichtet worden wären, und verweigert alle Identitätsbescheinigungsversuche. Dies wird durch Signieren oder MACing des Speichers wie unten beschrieben implementiert .
  • Der Speicher enthält nicht die ursprünglichen Identifikatoren. Da es sich bei der ID-Beglaubigung um eine Abfrage handelt, liefert der Aufrufer immer die zu beglaubigenden Identifikatoren. Der TEE muss nur überprüfen, ob diese mit den ursprünglichen Werten übereinstimmen. Das Speichern sicherer Hashes der ursprünglichen Werte anstelle der Werte ermöglicht diese Überprüfung.

Konstruktion

Um eine Implementierung mit den oben aufgeführten Eigenschaften zu erstellen, speichern Sie die von der ID abgeleiteten Werte in der folgenden Konstruktion S. Speichern Sie keine anderen Kopien der ID-Werte, mit Ausnahme der normalen Stellen im System, die ein Gerätebesitzer durch Rooten ändern kann:

S = D || HMAC(HBK, D)

Wo:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC ist die HMAC-Konstruktion mit einem geeigneten sicheren Hash (SHA-256 empfohlen)
  • HBK ist ein hardwaregebundener Schlüssel, der für keinen anderen Zweck verwendet wird
  • ID 1 ...ID n sind die ursprünglichen ID-Werte; Die Zuordnung eines bestimmten Werts zu einem bestimmten Index ist implementierungsabhängig, da verschiedene Geräte eine unterschiedliche Anzahl von Kennungen haben
  • || steht für Verkettung

Da die HMAC-Ausgaben eine feste Größe haben, sind keine Header oder andere Strukturen erforderlich, um einzelne ID-Hashes oder den HMAC von D zu finden , Berechnen von HMAC(HBK, D) und Vergleichen mit dem Wert in S, um zu verifizieren, dass keine einzelnen IDs modifiziert/beschädigt wurden. Außerdem müssen Implementierungen konstante Zeitvergleiche für alle einzelnen ID-Elemente und die Validierung von S verwenden. Die Vergleichszeit muss konstant sein, unabhängig von der Anzahl der bereitgestellten IDs und der korrekten Übereinstimmung aller Teile des Tests.

Hardware-Identifikatoren

Die ID-Bestätigung unterstützt die folgenden Hardwarekennungen:

  1. Markenname, wie von Build.BRAND in Android zurückgegeben
  2. Gerätename, wie von Build.DEVICE in Android zurückgegeben
  3. Produktname, wie von Build.PRODUCT in Android zurückgegeben
  4. Name des Herstellers, wie von Build.MANUFACTURER in Android zurückgegeben
  5. Modellname, wie von Build.MODEL in Android zurückgegeben
  6. Seriennummer
  7. IMEIs aller Radios
  8. MEIDs aller Funkgeräte

Um den Geräte-ID-Nachweis zu unterstützen, bestätigt ein Gerät diese Kennungen. Alle Geräte mit Android haben die ersten sechs und sie sind notwendig, damit diese Funktion funktioniert. Wenn das Gerät über integrierte Mobilfunkgeräte verfügt, muss das Gerät auch die Bestätigung für die IMEIs und/oder MEIDs der Funkgeräte unterstützen.

Die ID-Beglaubigung wird angefordert, indem eine Schlüsselbeglaubigung durchgeführt und die zu beglaubigenden Gerätekennungen in die Anfrage aufgenommen werden. Die Identifikatoren sind gekennzeichnet als:

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

Der zu bestätigende Bezeichner ist eine UTF-8-codierte Bytezeichenfolge. Dieses Format gilt auch für numerische Bezeichner. Jede zu bestätigende Kennung wird als UTF-8-codierte Zeichenfolge ausgedrückt.

Wenn das Gerät keine ID-Bestätigung unterstützt (oder destroyAttestationIds() zuvor aufgerufen wurde und das Gerät seine IDs nicht mehr bestätigen kann), schlägt jede Schlüsselbestätigungsanforderung, die eines oder mehrere dieser Tags enthält, mit ErrorCode::CANNOT_ATTEST_IDS fehl.

Wenn das Gerät die ID-Beglaubigung unterstützt und ein oder mehrere der oben genannten Tags in einer Schlüsselbeglaubigungsanforderung enthalten sind, überprüft das TEE, dass die mit jedem der Tags gelieferte Kennung mit seiner Kopie der Hardware-Kennungen übereinstimmt. Wenn eine oder mehrere Kennungen nicht übereinstimmen, schlägt die gesamte Attestierung mit ErrorCode::CANNOT_ATTEST_IDS fehl. Es gilt, dass derselbe Tag mehrfach geliefert wird. Dies kann zum Beispiel beim Attestieren von IMEIs nützlich sein: Ein Gerät kann mehrere Funkgeräte mit mehreren IMEIs haben. Eine Beglaubigungsanforderung ist gültig, wenn der mit jeder ATTESTATION_ID_IMEI gelieferte Wert mit einem der Funkgeräte des Geräts übereinstimmt. Gleiches gilt für alle anderen Tags.

Wenn die Beglaubigung erfolgreich ist, werden die beglaubigten IDs der Beglaubigungserweiterung (OID 1.3.6.1.4.1.11129.2.1.17) des ausgestellten Beglaubigungszertifikats hinzugefügt, wobei das Schema von oben verwendet wird. Änderungen gegenüber dem Keymaster 2-Bestätigungsschema sind fett gedruckt und kommentiert.

Java-API

Dieser Abschnitt dient nur zu Informationszwecken. Keymaster-Implementierer implementieren oder verwenden die Java-API weder. Dies wird bereitgestellt, um Implementierern zu helfen, zu verstehen, wie die Funktion von Anwendungen verwendet wird. Systemkomponenten können es unterschiedlich verwenden, weshalb es wichtig ist, dass dieser Abschnitt nicht als normativ behandelt wird.

,

Keystore bietet einen sichereren Ort zum kontrollierten Erstellen, Speichern und Verwenden von kryptografischen Schlüsseln. Wenn ein hardwaregestützter Schlüsselspeicher verfügbar ist und verwendet wird, ist das Schlüsselmaterial sicherer gegen die Extraktion aus dem Gerät, und Keymaster erzwingt Beschränkungen, die schwer zu umgehen sind.

Dies gilt jedoch nur, wenn bekannt ist, dass sich die Keystore-Schlüssel in einem hardwaregestützten Speicher befinden. In Keymaster 1 gab es keine Möglichkeit für Apps oder Remote-Server, zuverlässig zu überprüfen, ob dies der Fall war. Der Keystore-Daemon lud die verfügbare Keymaster-HAL und glaubte, was auch immer die HAL in Bezug auf die Hardware-Unterstützung von Schlüsseln sagte.

Um dies zu beheben, hat Keymasterdie Schlüsselbeglaubigung in Android 7.0 (Keymaster 2) und die ID-Beglaubigung in Android 8.0 (Keymaster 3) eingeführt.

Der Schlüsselnachweis zielt darauf ab, eine Möglichkeit zu bieten, um sicher zu bestimmen, ob ein asymmetrisches Schlüsselpaar hardwaregestützt ist, welche Eigenschaften der Schlüssel hat und welche Einschränkungen auf seine Verwendung angewendet werden.

Die ID-Bestätigung ermöglicht es dem Gerät, seine Hardwarekennungen wie Seriennummer oder IMEI nachzuweisen.

Schlüsselbescheinigung

Um den Schlüsselnachweis zu unterstützen, hat Android 7.1 eine Reihe von Tags, Typen und Methoden in die HAL eingeführt.

Stichworte

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

Typ

Keymaster 2 und darunter

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

AttestKey -Methode

Schlüsselmeister 3

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

Keymaster 2 und darunter

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 ist die Keymaster-Gerätestruktur.
  • keyToAttest ist das Schlüsselblob, das von generateKey zurückgegeben wird, für das die Beglaubigung erstellt wird.
  • attestParams ist eine Liste aller für die Beglaubigung erforderlichen Parameter. Dazu gehören Tag::ATTESTATION_CHALLENGE und möglicherweise Tag::RESET_SINCE_ID_ROTATION sowie Tag::APPLICATION_ID und Tag::APPLICATION_DATA . Die beiden letzteren sind zum Entschlüsseln des Schlüsselblobs erforderlich, wenn sie während der Schlüsselgenerierung angegeben wurden.
  • certChain ist der Ausgabeparameter, der ein Array von Zertifikaten zurückgibt. Eintrag 0 ist das Beglaubigungszertifikat, d. h. es beglaubigt den Schlüssel von keyToAttest und enthält die Beglaubigungserweiterung.

Die attestKey Methode wird als Public-Key-Operation für den attestierten Schlüssel betrachtet, da sie jederzeit aufgerufen werden kann und keine Autorisierungsbeschränkungen erfüllen muss. Wenn zum Beispiel der attestierte Schlüssel zur Verwendung eine Benutzerauthentifizierung benötigt, kann eine Attestierung ohne Benutzerauthentifizierung generiert werden.

Beglaubigungszertifikat

Das Beglaubigungszertifikat ist ein standardmäßiges X.509-Zertifikat mit einer optionalen Beglaubigungserweiterung, die eine Beschreibung des beglaubigten Schlüssels enthält. Das Zertifikat wird mit einem zertifizierten Beglaubigungsschlüssel signiert. Der Beglaubigungsschlüssel kann einen anderen Algorithmus verwenden als der zu beglaubigende Schlüssel.

Das Beglaubigungszertifikat enthält die Felder in der folgenden Tabelle und darf keine zusätzlichen Felder enthalten. Einige Felder geben einen festen Feldwert an. CTS-Tests validieren, dass der Zertifikatsinhalt genau wie definiert ist.

Zertifikat SEQUENZ

Feldname (siehe RFC 5280 ) Wert
tbsZertifikat TBSCertificate SEQUENZ
Signaturalgorithm AlgorithmIdentifier des Algorithmus, der zum Signieren des Schlüssels verwendet wird:
ECDSA für EC-Schlüssel, RSA für RSA-Schlüssel.
Signaturwert BIT STRING, Signatur berechnet auf ASN.1 DER-codiertem tbsCertificate.

TBSCertificate SEQUENZ

Feldname (siehe RFC 5280 ) Wert
version INTEGER 2 (bedeutet v3-Zertifikat)
serialNumber INTEGER 1 (fester Wert: auf allen Zertifikaten gleich)
signature AlgorithmusBezeichner des zum Signieren des Schlüssels verwendeten Algorithmus: ECDSA für EC-Schlüssel, RSA für RSA-Schlüssel.
issuer Entspricht dem Betrefffeld des Batch-Beglaubigungsschlüssels.
validity SEQUENCE von zwei Daten, die die Werte von Tag::ACTIVE_DATETIME und Tag::USAGE_EXPIRE_DATETIME enthalten. Diese Werte sind in Millisekunden seit dem 1. Januar 1970 angegeben. Siehe RFC 5280 für korrekte Datumsdarstellungen in Zertifikaten.
Wenn Tag::ACTIVE_DATETIME nicht vorhanden ist, verwenden Sie den Wert von Tag::CREATION_DATETIME . Wenn Tag::USAGE_EXPIRE_DATETIME nicht vorhanden ist, verwenden Sie das Ablaufdatum des Schlüsselzertifikats für die Stapelbeglaubigung.
subject CN = "Android Keystore Key" (fester Wert: auf allen Zertifikaten gleich)
subjectPublicKeyInfo SubjectPublicKeyInfo, das den attestierten öffentlichen Schlüssel enthält.
extensions/Key Usage digitalSignature: gesetzt, wenn der Schlüssel einen Zweck hat KeyPurpose::SIGN oder KeyPurpose::VERIFY . Alle anderen Bits nicht gesetzt.
extensions/CRL Distribution Points Wert offen
extensions/"attestation" Die OID ist 1.3.6.1.4.1.11129.2.1.17; der Inhalt wird im Abschnitt Attestation Extension weiter unten definiert. Wie bei allen X.509-Zertifikatserweiterungen wird der Inhalt als OCTET_STRING dargestellt, der eine DER-Codierung der Beglaubigung SEQUENCE enthält.

Bescheinigungserweiterung

Die attestation enthält eine vollständige Beschreibung der dem Schlüssel zugeordneten Keymaster-Berechtigungen in einer Struktur, die direkt den Berechtigungslisten entspricht, wie sie in Android und der Keymaster-HAL verwendet werden. Jedes Tag in einer Autorisierungsliste wird durch einen ASN.1 SEQUENCE Eintrag dargestellt, der explizit mit der Keymaster-Tag-Nummer gekennzeichnet ist, aber mit dem Typdeskriptor (vier höherwertige Bits) maskiert ist.

Beispielsweise ist in Keymaster 3 Tag::PURPOSE in types.hal als ENUM_REP | 1 definiert ENUM_REP | 1 . Für die Beglaubigungserweiterung wird der Wert ENUM_REP entfernt, sodass Tag 1 übrig bleibt. (Für Keymaster 2 und darunter ist KM_TAG_PURPOSE in keymaster_defs.h definiert.)

Werte werden gemäß dieser Tabelle auf einfache Weise in ASN.1-Typen übersetzt:

Keymaster-Typ Typ ASN.1
ENUM GANZE ZAHL
ENUM_REP SET von INTEGER
UINT GANZE ZAHL
UINT_REP SET von INTEGER
ULONG GANZE ZAHL
ULONG_REP SET von INTEGER
DATE INTEGER (Millisekunden seit dem 1. Januar 1970 00:00:00 GMT)
BOOL NULL (in Keymaster bedeutet Tag vorhanden wahr, abwesend bedeutet falsch.
Dieselbe Semantik gilt für die ASN.1-Codierung)
BIGNUM Derzeit nicht verwendet, daher ist keine Zuordnung definiert
BYTES OCTET_STRING

Schema

Der Inhalt der Beglaubigungserweiterung wird durch das folgende ASN.1-Schema beschrieben.

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),
}

KeyDescription-Felder

Die Felder keymasterVersion und attestationChallenge werden nach Position und nicht nach Tags identifiziert, sodass die Tags in der codierten Form nur den Feldtyp angeben. Die restlichen Felder werden implizit wie im Schema angegeben getaggt.

Feldname Typ Wert
attestationVersion GANZE ZAHL Version des Attestierungsschemas: 1, 2 oder 3.
attestationSecurity Sicherheitsstufe Die Sicherheitsstufe dieser Bescheinigung. Es ist möglich, Softwarebescheinigungen von hardwaregestützten Schlüsseln zu erhalten. Solchen Bescheinigungen kann nicht vertraut werden, wenn das Android-System kompromittiert ist.
keymasterVersion GANZE ZAHL Version des Keymaster-Geräts: 0, 1, 2, 3 oder 4.
keymasterSecurity Sicherheitsstufe Die Sicherheitsstufe der Keymaster-Implementierung.
attestationChallenge OCTET_STRING Wert von Tag::ATTESTATION_CHALLENGE , angegeben für die Beglaubigungsanforderung.
uniqueId OCTET_STRING Optionale eindeutige ID, vorhanden, wenn Schlüssel Tag::INCLUDE_UNIQUE_ID hat
softwareEnforced Autorisierungsliste Optionale Keymaster-Autorisierungen, die nicht vom TEE erzwungen werden, falls vorhanden.
teeEnforced Autorisierungsliste Optionale Keymaster-Autorisierungen, die ggf. vom TEE erzwungen werden.

AuthorizationList-Felder

AuthorizationList Felder sind alle optional und werden durch den Keymaster-Tag-Wert identifiziert, wobei die Typbits maskiert sind. Es wird explizites Tagging verwendet, sodass die Felder zur einfacheren Analyse auch ein Tag enthalten, das ihren ASN.1-Typ angibt.

Einzelheiten zu den Werten der einzelnen Felder finden Sie types.hal für Keymaster 3 und keymaster_defs.h für Keymaster 2 und darunter. Keymaster-Tag-Namen wurden in Feldnamen umgewandelt, indem das Präfix KM_TAG weggelassen und der Rest in Kamelschreibweise geändert wurde, sodass Tag::KEY_SIZE zu keySize wurde.

RootOfTrust-Felder

Die RootOfTrust Felder werden positionsbezogen identifiziert.

Feldname Typ Wert
verifiedBootKey OCTET_STRING Ein sicherer Hash des Schlüssels, der zum Verifizieren des Systemabbilds verwendet wird. SHA-256 empfohlen.
deviceLocked BOOLEAN True, wenn der Bootloader gesperrt ist, was bedeutet, dass nur signierte Images geflasht werden können und dass eine verifizierte Boot-Überprüfung durchgeführt wird.
verifiedBootState Verifizierter BootState Status des verifizierten Starts.
verifiedBootHash OCTET_STRING Eine Zusammenfassung aller Daten, die durch Verified Boot geschützt sind. Für Geräte, die die Android Verified Boot-Implementierung von Verified Boot verwenden, enthält dieser Wert den Digest der VBMeta-Struktur oder die Verified Boot-Metadatenstruktur. Weitere Informationen zur Berechnung dieses Werts finden Sie unter The VBMeta Digest

VerifiedBootState-Werte

Die Werte verifiedBootState haben folgende Bedeutung:

Wert Bedeutung
Verified Zeigt eine vollständige Vertrauenskette an, die sich vom Bootloader bis zu verifizierten Partitionen erstreckt, einschließlich des Bootloaders, der Bootpartition und aller verifizierten Partitionen.
In diesem Zustand ist der verifiedBootKey Wert der Hash des eingebetteten Zertifikats, d. h. das unveränderliche Zertifikat, das in das ROM eingebrannt ist.
Dieser Zustand entspricht dem grünen Boot-Zustand, wie er in der verifizierten Boot-Flow -Dokumentation dokumentiert ist.
SelfSigned Zeigt an, dass die Startpartition mit dem eingebetteten Zertifikat verifiziert wurde und die Signatur gültig ist. Der Bootloader zeigt eine Warnung und den Fingerabdruck des öffentlichen Schlüssels an, bevor der Bootvorgang fortgesetzt werden kann.
In diesem Zustand ist der verifiedBootKey Wert der Hash des selbstsignierenden Zertifikats.
Dieser Zustand entspricht dem gelben Boot-Zustand, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.
Unverified Zeigt an, dass ein Gerät frei modifiziert werden kann. Die Überprüfung der Geräteintegrität bleibt dem Benutzer überlassen. Der Bootloader zeigt dem Benutzer eine Warnung an, bevor der Startvorgang fortgesetzt werden kann.
In diesem Zustand ist der verifiedBootKey Wert leer.
Dieser Zustand entspricht dem orangefarbenen Boot-Zustand, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.
Failed Zeigt an, dass die Überprüfung des Geräts fehlgeschlagen ist. Kein Beglaubigungszertifikat enthält tatsächlich diesen Wert, da der Bootloader in diesem Zustand anhält. Es ist hier der Vollständigkeit halber enthalten.
Dieser Zustand entspricht dem roten Boot-Zustand, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.

SecurityLevel-Werte

Die Werte von securityLevel haben folgende Bedeutung:

Wert Bedeutung
Software Der Code, der das relevante Element (Bestätigung oder Schlüssel) erstellt oder verwaltet, ist im Android-System implementiert und könnte geändert werden, wenn dieses System kompromittiert wird.
TrustedEnvironment Der Code, der das relevante Element (Attestierung oder Schlüssel) erstellt oder verwaltet, wird in einer Trusted Execution Environment (TEE) implementiert. Es könnte geändert werden, wenn das TEE kompromittiert wird, aber das TEE ist sehr widerstandsfähig gegenüber einer Kompromittierung aus der Ferne und mäßig widerstandsfähig gegenüber einer Beeinträchtigung durch einen direkten Hardwareangriff.
StrongBox Der Code, der das relevante Element (Bestätigung oder Schlüssel) erstellt oder verwaltet, wird in einem dedizierten Hardware-Sicherheitsmodul implementiert. It could be altered if the hardware security module is compromised, but it is highly resistant to remote compromise and highly resistant to compromise by direct hardware attack.

Unique ID

The Unique ID is a 128-bit value that identifies the device, but only for a limited period of time. The value is computed with:

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

Where:

  • T is the "temporal counter value", computed by dividing the value of Tag::CREATION_DATETIME by 2592000000, dropping any remainder. T changes every 30 days (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C is the value of Tag::APPLICATION_ID
  • R is 1 if Tag::RESET_SINCE_ID_ROTATION is present in the attest_params parameter to the attest_key call, or 0 if the tag is not present.
  • HBK is a unique hardware-bound secret known to the Trusted Execution Environment and never revealed by it. The secret contains at least 128 bits of entropy and is unique to the individual device (probabilistic uniqueness is acceptable given the 128 bits of entropy). HBK should be derived from fused key material via HMAC or AES_CMAC.

Truncate the HMAC_SHA256 output to 128 bits.

Attestation keys and certificates

Two keys, one RSA and one ECDSA, and the corresponding certificate chains, are securely provisioned into the device.

Android 12 introduces Remote Key Provisioning, and Android 13 requires devices implement it. Remote Key Provisioning provides devices in the field with per-application, ECDSA P256 attestation certificates. These certificates are shorter-lived than the factory-provisioned certificates.

ID attestation

Android 8.0 includes optional support for ID attestation for devices with Keymaster 3. ID attestation allows the device to provide proof of its hardware identifiers, such as serial number or IMEI. Although an optional feature, it is highly recommended that all Keymaster 3 implementations provide support for it because being able to prove the device's identity enables use cases such as true zero-touch remote configuration to be more secure (because the remote side can be certain it is talking to the right device, not a device spoofing its identity).

ID attestation works by creating copies of the device's hardware identifiers that only the Trusted Execution Environment (TEE) can access before the device leaves the factory. A user may unlock the device's bootloader and change the system software and the identifiers reported by the Android frameworks. The copies of the identifiers held by the TEE cannot be manipulated in this way, ensuring that device ID attestation will only ever attest to the device's original hardware identifiers thereby thwarting spoofing attempts.

The main API surface for ID attestation builds on top of the existing key attestation mechanism introduced with Keymaster 2. When requesting an attestation certificate for a key held by keymaster, the caller may request that the device's hardware identifiers be included in the attestation certificate's metadata. If the key is held in the TEE, the certificate will chain back to a known root of trust. The recipient of such a certificate can verify that the certificate and its contents, including the hardware identifiers, were written by the TEE. When asked to include hardware identifiers in the attestation certificate, the TEE attests only to the identifiers held in its storage, as populated on the factory floor.

Storage properties

The storage that holds the device's identifiers needs to have these properties:

  • The values derived from the device's original identifiers are copied to the storage before the device leaves the factory.
  • The destroyAttestationIds() method can permanently destroy this copy of the identifier-derived data. Permanent destruction means the data is completely removed so neither a factory reset nor any other procedure performed on the device can restore it. This is especially important for devices where a user has unlocked the bootloader and changed the system software and modified the identifiers returned by Android frameworks.
  • RMA facilities should have the ability to generate fresh copies of the hardware identifier-derived data. This way, a device that passes through RMA can perform ID attestation again. The mechanism used by RMA facilities must be protected so that users cannot invoke it themselves, as that would allow them to obtain attestations of spoofed IDs.
  • No code other than Keymaster trusted app in the TEE is able to read the identifier-derived data kept in the storage.
  • The storage is tamper-evident: If the content of the storage has been modified, the TEE treats it the same as if the copies of the content had been destroyed and refuses all ID attestation attempts. This is implemented by signing or MACing the storage as described below .
  • The storage does not hold the original identifiers. Because ID attestation involves a challenge, the caller always supplies the identifiers to be attested. The TEE only needs to verify that these match the values they originally had. Storing secure hashes of the original values rather than the values enables this verification.

Construction

To create an implementation that has the properties listed above, store the ID-derived values in the following construction S. Do not store other copies of the ID values, excepting the normal places in the system, which a device owner may modify by rooting:

S = D || HMAC(HBK, D)

where:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC is the HMAC construction with an appropriate secure hash (SHA-256 recommended)
  • HBK is a hardware-bound key not used for any other purpose
  • ID 1 ...ID n are the original ID values; association of a particular value to a particular index is implementation-dependent, as different devices will have different numbers of identifiers
  • || represents concatenation

Because the HMAC outputs are fixed size, no headers or other structure are required to be able to find individual ID hashes, or the HMAC of D. In addition to checking provided values to perform attestation, implementations need to validate S by extracting D from S, computing HMAC(HBK, D) and comparing it to the value in S to verify that no individual IDs were modified/corrupted. Also, implementations must use constant-time comparisons for all individual ID elements and the validation of S. Comparison time must be constant regardless of the number of IDs provided and the correct matching of any part of the test.

Hardware identifiers

ID attestation supports the following hardware identifiers:

  1. Brand name, as returned by Build.BRAND in Android
  2. Device name, as returned by Build.DEVICE in Android
  3. Product name, as returned by Build.PRODUCT in Android
  4. Manufacturer name, as returned by Build.MANUFACTURER in Android
  5. Model name, as returned by Build.MODEL in Android
  6. Serial number
  7. IMEIs of all radios
  8. MEIDs of all radios

To support device ID attestation, a device attests to these identifiers. All devices running Android have the first six and they are necessary for this feature to work. If the device has any integrated cellular radios, the device must also support attestation for the IMEIs and/or MEIDs of the radios.

ID attestation is requested by performing a key attestation and including the device identifiers to attest in the request. The identifiers are tagged as:

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

The identifier to attest is a UTF-8 encoded byte string. This format applies to numerical identifiers, as well. Each identifier to attest is expressed as a UTF-8 encoded string.

If the device does not support ID attestation (or destroyAttestationIds() was previously called and the device can no longer attest its IDs), any key attestation request that includes one or more of these tags fails with ErrorCode::CANNOT_ATTEST_IDS .

If the device supports ID attestation and one or more of the above tags have been included in a key attestation request, the TEE verifies the identifier supplied with each of the tags matches its copy of the hardware identifiers. If one or more identifiers do not match, the entire attestation fails with ErrorCode::CANNOT_ATTEST_IDS . It is valid for the same tag to be supplied multiple times. This can be useful, for example, when attesting IMEIs: A device may have multiple radios with multiple IMEIs. An attestation request is valid if the value supplied with each ATTESTATION_ID_IMEI matches one of the device's radios. The same applies to all other tags.

If attestation is successful, the attested IDs is added to the attestation extension (OID 1.3.6.1.4.1.11129.2.1.17) of the issued attestation certificate, using the schema from above . Changes from the Keymaster 2 attestation schema are bolded , with comments.

Java API

This section is informational only. Keymaster implementers neither implement nor use the Java API. This is provided to help implementers understand how the feature is used by applications. System components may use it differently, which is why it's crucial this section not be treated as normative.