Schlüssel- und Ausweisbescheinigung

Keystore bietet einen sichereren Ort zum kontrollierten Erstellen, Speichern und Verwenden kryptografischer Schlüssel. Wenn ein hardwaregestützter Schlüsselspeicher verfügbar ist und verwendet wird, ist das Schlüsselmaterial sicherer gegen die Entnahme 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 im hardwaregestützten Speicher befinden. In Keymaster 1 gab es für Apps oder Remote-Server keine Möglichkeit, zuverlässig zu überprüfen, ob dies der Fall war. Der Keystore-Daemon lud den verfügbaren Keymaster-HAL und glaubte, was auch immer der HAL in Bezug auf die Hardware-Unterstützung von Schlüsseln sagte.

Um dies zu beheben, führte Keymaster die Schlüsselbescheinigung in Android 7.0 (Keymaster 2) und die ID-Bescheinigung in Android 8.0 (Keymaster 3) ein.

Die Schlüsselbescheinigung soll eine Möglichkeit bieten, genau zu bestimmen, ob ein asymmetrisches Schlüsselpaar hardwaregestützt ist, welche Eigenschaften der Schlüssel hat und welche Einschränkungen für seine Verwendung gelten.

Mit der ID-Bescheinigung kann das Gerät seine Hardware-Identifikatoren wie Seriennummer oder IMEI nachweisen.

Schlüsselbescheinigung

Um die Schlüsselbescheinigung 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 niedriger

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 niedriger

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 der von generateKey zurückgegebene Schlüsselblob, für den die Bescheinigung erstellt wird.
  • attestParams ist eine Liste aller für die Attestierung 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 letztgenannten sind zum Entschlüsseln des Schlüssel-Blobs erforderlich, wenn sie bei der Schlüsselgenerierung angegeben wurden.
  • certChain ist der Ausgabeparameter, der ein Array von Zertifikaten zurückgibt. Eintrag 0 ist das Attestierungszertifikat, d. h. es zertifiziert den Schlüssel von keyToAttest und enthält die Attestierungserweiterung.

Die attestKey Methode wird als öffentliche Schlüsseloperation für den attestierten Schlüssel betrachtet, da sie jederzeit aufgerufen werden kann und keine Autorisierungsbeschränkungen erfüllen muss. Wenn der attestierte Schlüssel beispielsweise eine Benutzerauthentifizierung erfordert, kann eine Attestierung ohne Benutzerauthentifizierung generiert werden.

Bescheinigungsurkunde

Das Attestierungszertifikat ist ein Standard-X.509-Zertifikat mit einer optionalen Attestierungserweiterung, die eine Beschreibung des attestierten Schlüssels enthält. Das Zertifikat wird mit einem zertifizierten Attestierungsschlüssel signiert. Der Attestierungsschlüssel verwendet möglicherweise einen anderen Algorithmus als der attestierte Schlüssel.

Das Bescheinigungszertifikat enthält die Felder in der folgenden Tabelle und darf keine zusätzlichen Felder enthalten. Einige Felder geben einen festen Feldwert an. CTS-Tests bestätigen, dass der Zertifikatsinhalt genau der Definition entspricht.

Zertifikatssequenz

Feldname (siehe RFC 5280 ) Wert
tbsZertifikat TBSCertificate-SEQUENZ
SignaturAlgorithmus AlgorithmusIdentifikator des zum Signieren des Schlüssels verwendeten Algorithmus:
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: bei allen Zertifikaten gleich)
signature AlgorithmusIdentifikator 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-Attestierungsschlüssels.
validity SEQUENZ von zwei Datumsangaben, die die Werte von Tag::ACTIVE_DATETIME und Tag::USAGE_EXPIRE_DATETIME enthält. Diese Werte werden seit dem 1. Januar 1970 in Millisekunden angegeben. Informationen zur korrekten Datumsdarstellung in Zertifikaten finden Sie in RFC 5280 .
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 Batch-Attestierungsschlüsselzertifikats.
subject CN = „Android Keystore Key“ (fester Wert: bei allen Zertifikaten gleich)
subjectPublicKeyInfo SubjectPublicKeyInfo, das den bestätigten öffentlichen Schlüssel enthält.
extensions/Key Usage digitalSignature: Wird festgelegt, wenn der Schlüssel den Zweck KeyPurpose::SIGN oder KeyPurpose::VERIFY hat. Alle anderen Bits sind nicht gesetzt.
extensions/CRL Distribution Points Wert noch offen
extensions/"attestation" Die OID ist 1.3.6.1.4.1.11129.2.1.17; Der Inhalt wird im Abschnitt „Bescheinigungserweiterung“ unten definiert. Wie bei allen X.509-Zertifikaterweiterungen wird der Inhalt als OCTET_STRING dargestellt, der eine DER-Kodierung der Attestierungssequenz enthält.

Erweiterung der Bescheinigung

Die attestation enthält eine vollständige Beschreibung der mit dem Schlüssel verknüpften Keymaster-Berechtigungen in einer Struktur, die direkt den Berechtigungslisten entspricht, wie sie in Android und im 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, der Typdeskriptor (vier höherwertige Bits) jedoch ausgeblendet ist.

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

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

Keymaster-Typ ASN.1-Typ
ENUM GANZE ZAHL
ENUM_REP SATZ von INTEGER
UINT GANZE ZAHL
UINT_REP SATZ von INTEGER
ULONG GANZE ZAHL
ULONG_REP SATZ von INTEGER
DATE INTEGER (Millisekunden seit 1. Januar 1970 00:00:00 GMT)
BOOL NULL (in Keymaster bedeutet vorhandener Tag „wahr“, „abwesend“ bedeutet „falsch“.
Die gleiche Semantik gilt für die ASN.1-Kodierung)
BIGNUM Wird derzeit nicht verwendet, daher ist keine Zuordnung definiert
BYTES OCTET_STRING

Schema

Der Inhalt der Attestierungserweiterung 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 anhand der Position und nicht anhand des Tags identifiziert, sodass die Tags im codierten Formular nur den Feldtyp angeben. Die übrigen Felder werden implizit entsprechend den Angaben im Schema getaggt.

Feldname Typ Wert
attestationVersion GANZE ZAHL Version des Attestierungsschemas: 1, 2 oder 3.
attestationSecurity Sicherheitsstufe Die Sicherheitsstufe dieser Bescheinigung. Es ist möglich, Software-Bescheinigungen von hardwaregestützten Schlüsseln zu erhalten. Solche Bescheinigungen können nicht vertrauenswürdig sein, 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 , der für die Attestierungsanforderung angegeben wird.
uniqueId OCTET_STRING Optionale eindeutige ID, vorhanden, wenn der Schlüssel Tag::INCLUDE_UNIQUE_ID hat
softwareEnforced Autorisierungsliste Optionale Keymaster-Autorisierungen, die ggf. nicht vom TEE erzwungen werden.
teeEnforced Autorisierungsliste Optional, 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 ausgeblendet 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 in 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 Kamel-Schreibweise geändert wurde, sodass Tag::KEY_SIZE zu keySize wurde.

RootOfTrust-Felder

Die RootOfTrust Felder werden positionell identifiziert.

Feldname Typ Wert
verifiedBootKey OCTET_STRING Ein sicherer Hash des Schlüssels, der zur Überprüfung 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-Prüfung durchgeführt wird.
verifiedBootState VerifiedBootState Status des verifizierten Startvorgangs.
verifiedBootHash OCTET_STRING Eine Zusammenfassung aller durch Verified Boot geschützten Daten. 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 unterThe VBMeta Digest

VerifiedBootState-Werte

Die Werte von 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 Startpartition und aller verifizierten Partitionen.
In diesem Zustand ist der verifiedBootKey Wert der Hash des eingebetteten Zertifikats, also des unveränderlichen Zertifikats, das in das ROM gebrannt ist.
Dieser Status entspricht dem Green- Boot-Status, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.
SelfSigned Zeigt an, dass die Startpartition mithilfe des eingebetteten Zertifikats überprüft 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 Status entspricht dem gelben Boot-Status, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.
Unverified Zeigt an, dass ein Gerät frei geändert werden kann. Die Überprüfung der Geräteintegrität bleibt dem Benutzer überlassen. Der Bootloader zeigt dem Benutzer eine Warnung an, bevor der Bootvorgang fortgesetzt werden kann.
In diesem Zustand ist der verifiedBootKey Wert leer.
Dieser Status entspricht dem orangefarbenen Boot-Status, wie in der verifizierten Boot-Flow -Dokumentation dokumentiert.
Failed Zeigt an, dass die Überprüfung des Geräts fehlgeschlagen ist. Tatsächlich enthält kein Attestierungszertifikat diesen Wert, da in diesem Zustand der Bootloader anhält. Der Vollständigkeit halber ist es hier enthalten.
Dieser Status entspricht dem roten Boot-Status, 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 (Bescheinigung 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 (Bescheinigung 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 resistent gegen eine Remote-Kompromittierung und mäßig resistent gegen eine Kompromittierung durch direkte Hardware-Angriffe.
StrongBox Der Code, der das relevante Element (Bescheinigung oder Schlüssel) erstellt oder verwaltet, ist in einem dedizierten Hardware-Sicherheitsmodul implementiert. Es könnte geändert werden, wenn das Hardware-Sicherheitsmodul kompromittiert wird, es ist jedoch äußerst resistent gegenüber einer Kompromittierung aus der Ferne und äußerst resistent gegenüber einer Kompromittierung durch direkte Hardware-Angriffe.

Eindeutige ID

Die Unique ID ist ein 128-Bit-Wert, der das Gerät identifiziert, jedoch nur für einen begrenzten Zeitraum. Der Wert wird berechnet 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 dividiert wird, wobei der Rest weggelassen wird. 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 dieser niemals preisgegeben wird. Das Geheimnis enthält mindestens 128 Entropiebits und ist für das einzelne Gerät einzigartig (wahrscheinliche Eindeutigkeit ist angesichts der 128 Entropiebits akzeptabel). HBK sollte aus fusioniertem Schlüsselmaterial über HMAC oder AES_CMAC abgeleitet werden.

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

Bescheinigungsschlüssel und Zertifikate

Zwei Schlüssel, ein RSA und ein ECDSA, sowie 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-Bescheinigungszertifikaten pro Anwendung. Diese Zertifikate haben eine kürzere Lebensdauer als die werkseitig bereitgestellten Zertifikate.

Mehrere IMEIs

Android 14 fügt Unterstützung für mehrere IMEIs im Android Key Attestation-Datensatz hinzu. OEMs können diese Funktion implementieren, indem sie ein KeyMint-Tag für eine zweite IMEI hinzufügen. Es kommt immer häufiger vor, dass Geräte über mehrere Mobilfunkgeräte verfügen, und OEMs können jetzt Geräte mit zwei IMEIs unterstützen.

OEMs müssen, sofern auf ihren Geräten vorhanden, über eine sekundäre IMEI verfügen, die für die KeyMint-Implementierung(en) bereitgestellt werden muss, damit diese Implementierungen diese auf die gleiche Weise bestätigen können wie die erste IMEI

Ausweisbescheinigung

Android 8.0 bietet optionale Unterstützung für die ID-Bescheinigung für Geräte mit Keymaster 3. Die ID-Bescheinigung ermöglicht es dem Gerät, einen Nachweis seiner Hardware-IDs wie Seriennummer oder IMEI zu erbringen. Obwohl es sich um eine optionale Funktion handelt, wird dringend empfohlen, dass alle Keymaster 3-Implementierungen diese unterstützen, da die Möglichkeit, die Identität des Geräts nachzuweisen, Anwendungsfälle wie eine echte Zero-Touch-Remotekonfiguration sicherer macht (da die Remote-Seite sicher sein kann). kommuniziert mit dem richtigen Gerät, nicht mit einem Gerät, das seine Identität fälscht).

Bei der ID-Bescheinigung werden Kopien der Hardware-IDs des Geräts erstellt, 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 vom TEE gespeicherten Kopien der Identifikatoren können auf diese Weise nicht manipuliert werden, wodurch sichergestellt wird, dass der Geräte-ID-Nachweis immer nur die ursprünglichen Hardware-Identifikatoren des Geräts bescheinigt, wodurch Spoofing-Versuche verhindert werden.

Die Haupt-API-Oberfläche für die ID-Bescheinigung baut auf dem vorhandenen Schlüsselbescheinigungsmechanismus auf, der mit Keymaster 2 eingeführt wurde. Beim Anfordern eines Bescheinigungszertifikats für einen von Keymaster gehaltenen Schlüssel kann der Aufrufer anfordern, dass die Hardware-IDs des Geräts in die Metadaten des Bescheinigungszertifikats aufgenommen werden. Wenn der Schlüssel im TEE gespeichert ist, wird das Zertifikat zu einem bekannten Vertrauensanker zurückverkettet. Der Empfänger eines solchen Zertifikats kann überprüfen, ob das Zertifikat und sein Inhalt, einschließlich der Hardware-IDs, vom TEE geschrieben wurden. Wenn das TEE aufgefordert wird, Hardware-Identifikatoren in das Attestierungszertifikat aufzunehmen, bestätigt es nur die in seinem Speicher gespeicherten Identifikatoren, die in der Fabrikhalle eingegeben wurden.

Speichereigenschaften

Der Speicher, der die Gerätekennungen enthält, muss über die folgenden Eigenschaften verfügen:

  • Die aus den Originalkennungen 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 vom Identifikator abgeleiteten Daten dauerhaft zerstören. Permanente Zerstörung bedeutet, dass die Daten vollständig entfernt werden, sodass sie weder durch Zurücksetzen auf die Werkseinstellungen noch durch andere am Gerät durchgeführte Verfahren wiederhergestellt werden können. Dies ist besonders wichtig für Geräte, bei denen ein Benutzer den Bootloader entsperrt, die Systemsoftware geändert und die von Android-Frameworks zurückgegebenen Bezeichner geändert hat.
  • RMA-Einrichtungen sollten in der Lage sein, neue Kopien der von der Hardware-ID abgeleiteten Daten zu erstellen. Auf diese Weise kann ein Gerät, das die RMA durchläuft, erneut eine ID-Bestätigung durchführen. Der von RMA-Einrichtungen verwendete Mechanismus muss geschützt werden, damit Benutzer ihn nicht selbst aufrufen können, da er dadurch Bescheinigungen über gefälschte IDs erhalten könnte.
  • Kein anderer Code als die vertrauenswürdige Keymaster-App im TEE ist in der Lage, die im Speicher gespeicherten, von der Kennung abgeleiteten Daten zu lesen.
  • Der Speicher ist manipulationssicher: Wenn der Inhalt des Speichers geändert wurde, behandelt das TEE dies so, als ob die Kopien des Inhalts zerstört worden wären, und lehnt alle Versuche zur Identifizierung der Identität ab. Dies wird durch Signieren oder MACing des Speichers wie unten beschrieben implementiert.
  • Der Speicher enthält nicht die ursprünglichen Kennungen. Da die ID-Bestätigung eine Herausforderung darstellt, stellt der Anrufer immer die zu bescheinigenden Identifikatoren bereit. Das TEE muss lediglich überprüfen, ob diese mit den ursprünglichen Werten übereinstimmen. Das Speichern sicherer Hashes der Originalwerte 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 nicht für andere Zwecke verwendet wird
  • ID 1 ...ID n sind die ursprünglichen ID-Werte; Die Zuordnung eines bestimmten Werts zu einem bestimmten Index hängt von der Implementierung ab, 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 finden zu können. Zusätzlich zur Überprüfung der bereitgestellten Werte zur Durchführung der Bescheinigung müssen Implementierungen S validieren, indem sie D aus S extrahieren , Berechnen von HMAC(HBK, D) und Vergleichen mit dem Wert in S, um sicherzustellen, dass keine einzelnen IDs geändert/beschädigt wurden. Außerdem müssen Implementierungen zeitkonstante Vergleiche für alle einzelnen ID-Elemente und die Validierung von S verwenden. Die Vergleichszeit muss unabhängig von der Anzahl der bereitgestellten IDs und der korrekten Übereinstimmung eines Teils des Tests konstant sein.

Hardware-IDs

Der ID-Nachweis unterstützt die folgenden Hardware-IDs:

  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. Herstellername, 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 Radios

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

Die ID-Bescheinigung wird angefordert, indem eine Schlüsselbescheinigung durchgeführt und die zu bescheinigenden Gerätekennungen in die Anfrage aufgenommen werden. Die Bezeichner sind wie folgt gekennzeichnet:

  • 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 attestierende Bezeichner ist eine UTF-8-codierte Bytefolge. Dieses Format gilt auch für numerische Bezeichner. Jeder zu attestierende Bezeichner wird als UTF-8-codierte Zeichenfolge ausgedrückt.

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

Wenn das Gerät die ID-Bescheinigung unterstützt und einer oder mehrere der oben genannten Tags in einer Schlüsselbescheinigungsanforderung enthalten sind, überprüft das TEE, ob die mit jedem der Tags bereitgestellte Kennung mit seiner Kopie der Hardware-Kennungen übereinstimmt. Wenn ein oder mehrere Bezeichner nicht übereinstimmen, schlägt die gesamte Bescheinigung mit ErrorCode::CANNOT_ATTEST_IDS fehl. Es ist zulässig, dass dasselbe Tag mehrmals bereitgestellt wird. Dies kann beispielsweise bei der Bescheinigung von IMEIs nützlich sein: Ein Gerät kann über mehrere Funkgeräte mit mehreren IMEIs verfügen. Eine Bescheinigungsanforderung ist gültig, wenn der mit jeder ATTESTATION_ID_IMEI bereitgestellte Wert mit einem der Funkgeräte des Geräts übereinstimmt. Das Gleiche gilt auch für alle anderen Tags.

Wenn die Attestierung erfolgreich ist, werden die attestierten IDs der Attestierungserweiterung (OID 1.3.6.1.4.1.11129.2.1.17) des ausgestellten Attestierungszertifikats hinzugefügt, wobei das Schema von oben verwendet wird. Änderungen gegenüber dem Keymaster 2-Bescheinigungsschema sind fett gedruckt und mit Kommentaren versehen.

Java-API

Dieser Abschnitt dient nur zur Information. 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 verwenden es möglicherweise unterschiedlich, weshalb es wichtig ist, dass dieser Abschnitt nicht als normativ behandelt wird.