Die Verfügbarkeit einer vertrauenswürdigen Ausführungsumgebung in einem System on a Chip (SoC) bietet Android-Geräten die Möglichkeit, hardwaregestützte, starke Sicherheitsdienste für das Android-Betriebssystem, Plattformdienste und sogar Apps von Drittanbietern bereitzustellen. Entwickler, die Android-spezifische Erweiterungen suchen, sollten android.security.keystore aufrufen.
Vor Android 6.0 verfügte Android bereits über eine einfache, hardwaregestützte API für Kryptodienste, die durch die Versionen 0.2 und 0.3 des Keymaster Hardware Abstraction Layer (HAL) bereitgestellt wurde. Keystore stellte digitale Signatur- und Verifizierungsvorgänge sowie die Generierung und den Import asymmetrischer Signaturschlüsselpaare bereit. Dies ist bereits auf vielen Geräten implementiert, es gibt jedoch viele Sicherheitsziele, die mit nur einer Signatur-API nicht einfach erreicht werden können. Keystore in Android 6.0 hat die Keystore-API erweitert, um ein breiteres Spektrum an Funktionen bereitzustellen.
In Android 6.0 fügte Keystore symmetrische kryptografische Grundelemente , AES und HMAC sowie ein Zugriffskontrollsystem für hardwaregestützte Schlüssel hinzu. Zugriffskontrollen werden während der Schlüsselgenerierung festgelegt und für die Lebensdauer des Schlüssels durchgesetzt. Schlüssel können so eingeschränkt werden, dass sie nur nach Authentifizierung des Benutzers und nur für bestimmte Zwecke oder mit bestimmten kryptografischen Parametern verwendet werden können. Weitere Informationen finden Sie auf den Seiten Autorisierungs-Tags und -Funktionen .
Zusätzlich zur Erweiterung des Bereichs kryptografischer Grundelemente hat Keystore in Android 6.0 Folgendes hinzugefügt:
- Ein Nutzungskontrollschema, mit dem die Schlüsselnutzung eingeschränkt werden kann, um das Risiko einer Sicherheitsbeeinträchtigung aufgrund des Missbrauchs von Schlüsseln zu verringern
- Ein Zugriffskontrollschema, um die Beschränkung von Schlüsseln auf bestimmte Benutzer, Clients und einen definierten Zeitraum zu ermöglichen
In Android 7.0 fügte Keymaster 2 Unterstützung für Schlüsselnachweis und Versionsbindung hinzu. Die Schlüsselbescheinigung stellt öffentliche Schlüsselzertifikate bereit, die eine detaillierte Beschreibung des Schlüssels und seiner Zugriffskontrollen enthalten, um die Existenz des Schlüssels in sicherer Hardware und seine Konfiguration aus der Ferne überprüfbar zu machen.
Die Versionsbindung bindet Schlüssel an das Betriebssystem und die Patch-Level-Version. Dadurch wird sichergestellt, dass ein Angreifer, der eine Schwachstelle in einer alten Version des Systems oder der TEE-Software entdeckt, ein Gerät nicht auf die anfällige Version zurücksetzen und mit der neueren Version erstellte Schlüssel verwenden kann. Wenn außerdem ein Schlüssel mit einer bestimmten Version und Patch-Ebene auf einem Gerät verwendet wird, das auf eine neuere Version oder Patch-Ebene aktualisiert wurde, wird der Schlüssel aktualisiert, bevor er verwendet werden kann, und die vorherige Version des Schlüssels wird ungültig. Wenn das Gerät aktualisiert wird, „rasten“ die Tasten zusammen mit dem Gerät nach vorne, aber jede Rückstellung des Geräts auf eine frühere Version führt dazu, dass die Tasten unbrauchbar werden.
In Android 8.0 wechselte Keymaster 3 von der alten C-Struktur Hardware Abstraction Layer (HAL) zur C++-HAL-Schnittstelle, die aus einer Definition in der neuen Hardware Interface Definition Language (HIDL) generiert wurde. Im Rahmen der Änderung haben sich viele der Argumenttypen geändert, obwohl Typen und Methoden eine Eins-zu-eins-Entsprechung mit den alten Typen und den HAL-Strukturmethoden aufweisen. Weitere Einzelheiten finden Sie auf der Seite „Funktionen“ .
Zusätzlich zu dieser Schnittstellenüberarbeitung erweiterte Android 8.0 die Attestierungsfunktion von Keymaster 2 um die Unterstützung der ID-Attestierung . Die ID-Bescheinigung bietet einen begrenzten und optionalen Mechanismus zur starken Bescheinigung von Hardware-Identifikatoren, wie z. B. der Seriennummer des Geräts, dem Produktnamen und der Telefon-ID (IMEI/MEID). Um diesen Zusatz zu implementieren, hat Android 8.0 das ASN.1-Nachweisschema geändert, um einen ID-Nachweis hinzuzufügen. Keymaster-Implementierungen müssen einen sicheren Weg zum Abrufen der relevanten Datenelemente finden und einen Mechanismus zum sicheren und dauerhaften Deaktivieren der Funktion definieren.
Zu den Updates in Android 9 gehörten:
- Update auf Keymaster 4
- Unterstützung für eingebettete sichere Elemente
- Unterstützung für sicheren Schlüsselimport
- Unterstützung für 3DES-Verschlüsselung
- Änderungen an der Versionsbindung, sodass boot.img und system.img separat festgelegte Versionen haben, um unabhängige Updates zu ermöglichen
Glossar
Hier finden Sie einen kurzen Überblick über Keystore-Komponenten und ihre Beziehungen.
AndroidKeystore ist die Android Framework API und Komponente, die von Apps verwendet wird, um auf Keystore-Funktionen zuzugreifen. Es wird als Erweiterung der Standard-APIs der Java Cryptography Architecture implementiert und besteht aus Java-Code, der im eigenen Prozessraum der App ausgeführt wird. AndroidKeystore
erfüllt App-Anfragen zum Keystore-Verhalten, indem es sie an den Keystore-Daemon weiterleitet.
Der Keystore-Daemon ist ein Android-System-Daemon, der über eine Binder-API Zugriff auf alle Keystore-Funktionen bietet. Es ist für die Speicherung von „Schlüssel-Blobs“ verantwortlich, die das eigentliche geheime Schlüsselmaterial verschlüsselt enthalten, sodass Keystore sie speichern, aber nicht verwenden oder offenlegen kann.
keymasterd ist ein HIDL-Server, der Zugriff auf den Keymaster TA bietet. (Dieser Name ist nicht standardisiert und dient konzeptionellen Zwecken.)
Keymaster TA (vertrauenswürdige Anwendung) ist die Software, die in einem sicheren Kontext ausgeführt wird, meist in TrustZone auf einem ARM-SoC, die alle sicheren Keystore-Vorgänge bereitstellt, Zugriff auf das Rohschlüsselmaterial hat und alle Zugriffskontrollbedingungen für Schlüssel validiert , usw.
LockSettingsService ist die Android-Systemkomponente, die für die Benutzerauthentifizierung, sowohl Passwort als auch Fingerabdruck, verantwortlich ist. Es ist nicht Teil von Keystore, aber relevant, da viele Keystore-Schlüsselvorgänge eine Benutzerauthentifizierung erfordern. LockSettingsService
interagiert mit dem Gatekeeper TA und dem Fingerprint TA, um Authentifizierungstoken zu erhalten, die er dem Keystore-Daemon bereitstellt und die letztendlich von der Keymaster TA-Anwendung verwendet werden.
Gatekeeper TA (vertrauenswürdige Anwendung) ist eine weitere Komponente, die im sicheren Kontext ausgeführt wird und für die Authentifizierung von Benutzerkennwörtern und die Generierung von Authentifizierungstokens verantwortlich ist, mit denen dem Keymaster TA nachgewiesen werden kann, dass für einen bestimmten Benutzer zu einem bestimmten Zeitpunkt eine Authentifizierung durchgeführt wurde.
Fingerprint TA (vertrauenswürdige Anwendung) ist eine weitere Komponente, die im sicheren Kontext ausgeführt wird und für die Authentifizierung von Benutzerfingerabdrücken und die Generierung von Authentifizierungstokens verantwortlich ist, die dem Keymaster TA nachweisen, dass zu einem bestimmten Zeitpunkt eine Authentifizierung für einen bestimmten Benutzer durchgeführt wurde.
Die Architektur
Die Android Keystore API und der zugrunde liegende Keymaster HAL bieten einen grundlegenden, aber ausreichenden Satz kryptografischer Grundelemente, um die Implementierung von Protokollen mit zugriffskontrollierten, hardwaregestützten Schlüsseln zu ermöglichen.
Der Keymaster HAL ist eine vom OEM bereitgestellte, dynamisch ladbare Bibliothek, die vom Keystore-Dienst zur Bereitstellung hardwaregestützter kryptografischer Dienste verwendet wird. Um die Sicherheit zu gewährleisten, führen HAL-Implementierungen keine sensiblen Vorgänge im Benutzerbereich oder sogar im Kernelbereich aus. Sensible Vorgänge werden an einen sicheren Prozessor delegiert, der über eine Kernel-Schnittstelle erreicht wird. Die resultierende Architektur sieht folgendermaßen aus:

Abbildung 1. Zugriff auf Keymaster
Innerhalb eines Android-Geräts besteht der „Client“ des Keymaster HAL aus mehreren Schichten (z. B. App, Framework, Keystore-Daemon), die für die Zwecke dieses Dokuments jedoch ignoriert werden können. Dies bedeutet, dass die beschriebene Keymaster-HAL-API eine Low-Level-API ist, von plattforminternen Komponenten verwendet wird und nicht für App-Entwickler verfügbar ist. Die übergeordnete API wird auf der Android-Entwicklerseite beschrieben.
Der Zweck des Keymaster HAL besteht nicht darin, die sicherheitsrelevanten Algorithmen zu implementieren, sondern nur darin, Anfragen an die sichere Welt zu marschieren und zu entmarshalieren. Das Wire-Format ist durch die Implementierung definiert.
Kompatibilität mit früheren Versionen
Der Keymaster 1 HAL ist völlig inkompatibel mit den zuvor veröffentlichten HALs, z. B. Keymaster 0.2 und 0.3. Um die Interoperabilität auf Geräten mit Android 5.0 und früher zu erleichtern, die mit den älteren Keymaster-HALs gestartet wurden, stellt Keystore einen Adapter bereit, der den Keymaster 1-HAL mit Aufrufen an die vorhandene Hardwarebibliothek implementiert. Das Ergebnis kann nicht den vollen Funktionsumfang des Keymaster 1 HAL bieten. Insbesondere werden nur RSA- und ECDSA-Algorithmen unterstützt und die gesamte Durchsetzung der Schlüsselautorisierung wird vom Adapter in der nicht sicheren Welt durchgeführt.
Keymaster 2 hat die HAL-Schnittstelle weiter vereinfacht, indem die get_supported_*
Methoden entfernt wurden und der Methode finish()
erlaubt wurde, Eingaben zu akzeptieren. Dies reduziert die Anzahl der Roundtrips zum TEE in Fällen, in denen die Eingabe auf einmal verfügbar ist, und vereinfacht die Implementierung der AEAD-Entschlüsselung.
In Android 8.0 wechselte Keymaster 3 von der C-Struktur-HAL im alten Stil zur C++-HAL-Schnittstelle, die aus einer Definition in der neuen Hardware Interface Definition Language (HIDL) generiert wurde. Eine HAL-Implementierung neuen Stils wird erstellt, indem die generierte IKeymasterDevice
Klasse in Unterklassen unterteilt und die rein virtuellen Methoden implementiert werden. Im Rahmen der Änderung haben sich viele der Argumenttypen geändert, obwohl Typen und Methoden eine Eins-zu-eins-Entsprechung mit den alten Typen und den HAL-Strukturmethoden aufweisen.
HIDL-Übersicht
Die Hardware Interface Definition Language (HIDL) bietet einen von der Implementierungssprache unabhängigen Mechanismus zum Spezifizieren von Hardwareschnittstellen. Die HIDL-Tools unterstützen derzeit die Generierung von C++- und Java-Schnittstellen. Es wird erwartet, dass die meisten TEE-Implementierer (Trusted Execution Environment) die C++-Tools bequemer finden werden, daher wird in diesem Dokument nur die C++-Darstellung behandelt.
HIDL-Schnittstellen bestehen aus einer Reihe von Methoden, ausgedrückt als:
methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);
Es gibt verschiedene vordefinierte Typen, und HALs können neue Aufzählungs- und Strukturtypen definieren. Weitere Einzelheiten zu HIDL finden Sie im Abschnitt „Referenz“ .
Eine Beispielmethode aus Keymaster 3 IKeymasterDevice.hal
ist:
generateKey(vec<KeyParameter> keyParams) generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
Dies entspricht dem Folgenden aus der keymaster2-HAL:
keymaster_error_t (*generate_key)( const struct keymaster2_device* dev, const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics);
In der HIDL-Version wird das dev
Argument entfernt, da es implizit ist. Das Argument params
ist keine Struktur mehr, die einen Zeiger enthält, der auf ein Array von key_parameter_t
Objekten verweist, sondern ein vec
(Vektor), der KeyParameter
Objekte enthält. Die Rückgabewerte werden in der „ generates
“-Klausel aufgelistet, einschließlich eines Vektors von uint8_t
Werten für den Schlüsselblob.
Die vom HIDL-Compiler generierte virtuelle C++-Methode lautet:
Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams, generateKey_cb _hidl_cb) override;
Dabei ist generateKey_cb
ein Funktionszeiger, der wie folgt definiert ist:
std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob, const KeyCharacteristics& keyCharacteristics)>
Das heißt, generateKey_cb
ist eine Funktion, die die in der „generate“-Klausel aufgeführten Rückgabewerte entgegennimmt. Die HAL-Implementierungsklasse überschreibt diese Methode generateKey
“ und ruft den Funktionszeiger generateKey_cb
“ auf, um das Ergebnis der Operation an den Aufrufer zurückzugeben. Beachten Sie, dass der Aufruf des Funktionszeigers synchron ist. Der Aufrufer ruft generateKey
auf und „ generateKey
ruft den bereitgestellten Funktionszeiger auf, der vollständig ausgeführt wird und die Kontrolle an die generateKey
-Implementierung zurückgibt, die dann an den Aufrufer zurückkehrt.
Ein detailliertes Beispiel finden Sie in der Standardimplementierung in hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp
. Die Standardimplementierung bietet Abwärtskompatibilität für Geräte mit keymaster0-, keymaster1- oder keymaster2-HALS im alten Stil.
Zugangskontrolle
Die grundlegendste Regel der Keystore-Zugriffskontrolle besteht darin, dass jede App über einen eigenen Namespace verfügt. Aber für jede Regel gibt es eine Ausnahme. Keystore verfügt über einige hartcodierte Karten, die bestimmten Systemkomponenten den Zugriff auf bestimmte andere Namespaces ermöglichen. Dies ist ein sehr einfaches Instrument, da es einer Komponente die volle Kontrolle über einen anderen Namespace gibt. Und dann ist da noch die Frage der Herstellerkomponenten als Clients für Keystore. Wir haben derzeit keine Möglichkeit, einen Namensraum für Anbieterkomponenten, beispielsweise WPA-Supplicant, einzurichten.
Um Anbieterkomponenten zu berücksichtigen und die Zugriffskontrolle ohne hartcodierte Ausnahmen zu verallgemeinern, führt Keystore 2.0 Domänen und SELinux-Namespaces ein.
Keystore-Domänen
Mit Keystore-Domänen können wir Namespaces von UIDs entkoppeln. Clients, die auf einen Schlüssel im Keystore zugreifen, müssen die Domäne, den Namensraum und den Alias angeben, auf die sie zugreifen möchten. Anhand dieses Tupels und der Identität des Anrufers können wir bestimmen, auf welchen Schlüssel der Anrufer zugreifen möchte und ob er über die entsprechenden Berechtigungen verfügt.
Wir führen fünf Domänenparameter ein, die steuern, wie auf Schlüssel zugegriffen werden kann. Sie steuern die Semantik des Namespace-Parameters des Schlüsseldeskriptors und die Art und Weise, wie die Zugriffskontrolle durchgeführt wird.
-
DOMAIN_APP
: Die App-Domäne deckt das Legacy-Verhalten ab. Die Java Keystore SPI verwendet diese Domäne standardmäßig. Bei Verwendung dieser Domäne wird das Namespace-Argument ignoriert und stattdessen die UID des Aufrufers verwendet. Der Zugriff auf diese Domäne wird durch das Keystore-Label der Klassekeystore_key
in der SELinux-Richtlinie gesteuert. -
DOMAIN_SELINUX
: Diese Domäne gibt an, dass der Namespace eine Bezeichnung in der SELinux-Richtlinie hat. Der Namespace-Parameter wird nachgeschlagen und in einen Zielkontext übersetzt, und es wird eine Berechtigungsprüfung für den aufrufenden SELinux-Kontext für die Klassekeystore_key
durchgeführt. Wenn die Berechtigung für den angegebenen Vorgang eingerichtet wurde, wird das vollständige Tupel für die Schlüsselsuche verwendet. -
DOMAIN_GRANT
: Die Grant-Domäne gibt an, dass der Namespace-Parameter eine Grant-ID ist. Der Alias-Parameter wird ignoriert. SELinux-Prüfungen werden durchgeführt, wenn die Bewilligung erstellt wird. Die weitere Zugriffskontrolle prüft nur, ob die UID des Anrufers mit der UID des Berechtigten der angeforderten Bewilligung übereinstimmt. -
DOMAIN_KEY_ID
: Diese Domäne gibt an, dass der Namespace-Parameter eine eindeutige Schlüssel-ID ist. Der Schlüssel selbst wurde möglicherweise mitDOMAIN_APP
oderDOMAIN_SELINUX
erstellt. Die Berechtigungsprüfung wird durchgeführt, nachdem diedomain
und dernamespace
auf die gleiche Weise aus der Schlüsseldatenbank geladen wurden, als ob der Blob durch das Domänen-, Namespace- und Alias-Tupel geladen worden wäre. Der Grundgedanke für die Schlüssel-ID-Domäne ist Kontinuität. Wenn Sie über einen Alias auf einen Schlüssel zugreifen, werden nachfolgende Aufrufe möglicherweise mit anderen Schlüsseln ausgeführt, da möglicherweise ein neuer Schlüssel generiert oder importiert und an diesen Alias gebunden wurde. Die Schlüssel-ID ändert sich jedoch nie. Wenn man also einen Schlüssel nach Schlüssel-ID verwendet, nachdem er einmal mit dem Alias aus der Keystore-Datenbank geladen wurde, kann man sicher sein, dass es sich um denselben Schlüssel handelt, solange die Schlüssel-ID noch existiert. Diese Funktionalität steht App-Entwicklern nicht zur Verfügung. Stattdessen wird es innerhalb der Android Keystore SPI verwendet, um ein konsistenteres Erlebnis zu bieten, selbst wenn es gleichzeitig auf unsichere Weise verwendet wird. -
DOMAIN_BLOB
: Die Blob-Domäne gibt an, dass der Aufrufer das Blob selbst verwaltet. Dies wird für Clients verwendet, die auf den Keystore zugreifen müssen, bevor die Datenpartition bereitgestellt wird. Der Schlüsselblob ist imblob
des Schlüsseldeskriptors enthalten.
Mithilfe der SELinux-Domäne können wir Herstellerkomponenten Zugriff auf ganz bestimmte Keystore-Namespaces gewähren, die von Systemkomponenten wie dem Einstellungsdialog gemeinsam genutzt werden können.
SELinux-Richtlinie für keystore_key
Namespace-Bezeichnungen werden mithilfe der Datei keystore2_key_context
konfiguriert.
Jede Zeile in diesen Dateien ordnet eine numerische Namespace-ID einem SELinux-Label zu. Zum Beispiel,
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share keystore keys. 102 u:object_r:wifi_key:s0
Nachdem wir auf diese Weise einen neuen Schlüsselnamensraum eingerichtet haben, können wir durch Hinzufügen einer entsprechenden Richtlinie Zugriff darauf gewähren. Damit wpa_supplicant
beispielsweise Schlüssel im neuen Namespace abrufen und verwenden kann, würden wir die folgende Zeile zu hal_wifi_supplicant.te
hinzufügen:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
Nach der Einrichtung des neuen Namensraums kann AndroidKeyStore nahezu wie gewohnt genutzt werden. Der einzige Unterschied besteht darin, dass die Namespace-ID angegeben werden muss. Zum Laden und Importieren von Schlüsseln aus und in Keystore wird die Namespace-ID mithilfe von AndroidKeyStoreLoadStoreParameter
angegeben. Zum Beispiel,
import android.security.keystore2.AndroidKeyStoreLoadStoreParameter; import java.security.KeyStore; KeyStore keystore = KeyStore.getInstance("AndroidKeyStore"); keystore.load(new AndroidKeyStoreLoadStoreParameter(102));
Um einen Schlüssel in einem bestimmten Namespace zu generieren, muss die Namespace-ID mit KeyGenParameterSpec.Builder#setNamespace():
import android.security.keystore.KeyGenParameterSpec; KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder(); specBuilder.setNamespace(102);
Die folgenden Kontextdateien können zum Konfigurieren von Keystore 2.0 SELinux-Namespaces verwendet werden. Jede Partition verfügt über einen anderen reservierten Bereich von 10.000 Namespace-IDs, um Kollisionen zu vermeiden.
Partition | Reichweite | Konfigurationsdateien |
---|---|---|
System | 0 ... 9.999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts |
Erweitertes System | 10.000 ... 19.999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts |
Produkt | 20.000 ... 29.999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts |
Verkäufer | 30.000 ... 39.999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts |
Der Client fordert den Schlüssel an, indem er die SELinux-Domäne und den gewünschten virtuellen Namespace, in diesem Fall "wifi_key"
, anhand seiner numerischen ID anfragt.
Darüber hinaus wurden die folgenden Namensräume definiert. Wenn sie Sonderregeln ersetzen, gibt die folgende Tabelle die UID an, der sie früher entsprachen.
Namespace-ID | SEPolicy-Label | UID | Beschreibung |
---|---|---|---|
0 | su_key | N / A | Super-User-Schlüssel. Wird nur zum Testen von Userdebug- und Eng-Builds verwendet. Nicht relevant für Benutzer-Builds. |
1 | shell_key | N / A | Namespace, der für die Shell verfügbar ist. Wird hauptsächlich zum Testen verwendet, kann aber auch für Benutzer-Builds über die Befehlszeile verwendet werden. |
100 | vold_key | N / A | Zur Verwendung durch vold bestimmt. |
101 | odsing_key | N / A | Wird vom Signaturdämon auf dem Gerät verwendet. |
102 | wifi_key | AID_WIFI(1010) | Wird vom Wifi-Sybsystem von Android einschließlich wpa_supplicant verwendet. |
120 | resume_on_reboot_key | AID_SYSTEM(1000) | Wird vom Android-Systemserver verwendet, um die Wiederaufnahme beim Neustart zu unterstützen. |
Greifen Sie auf Vektoren zu
Die SELinux-Klasse keystore_key
ist ziemlich in die Jahre gekommen und einige der Berechtigungen, wie zum Beispiel verify
oder sign
haben ihre Bedeutung verloren. Hier ist der neue Satz von Berechtigungen, keystore2_key
, den Keystore 2.0 durchsetzen wird.
Erlaubnis | Bedeutung |
---|---|
delete | Wird beim Entfernen von Schlüsseln aus dem Keystore überprüft. |
get_info | Wird überprüft, wenn die Metadaten eines Schlüssels angefordert werden. |
grant | Der Aufrufer benötigt diese Berechtigung, um eine Gewährung für den Schlüssel im Zielkontext zu erstellen. |
manage_blob | Der Aufrufer kann DOMAIN_BLOB für den angegebenen SELinux-Namespace verwenden und so Blobs selbst verwalten. Dies ist besonders nützlich für Vold. |
rebind | Diese Berechtigung steuert, ob ein Alias an einen neuen Schlüssel zurückgebunden werden darf. Dies ist zum Einfügen erforderlich und impliziert, dass der zuvor gebundene Schlüssel gelöscht wird. Im Grunde handelt es sich um eine Einfügeberechtigung, die jedoch die Semantik des Keystores besser erfasst. |
req_forced_op | Clients mit dieser Berechtigung können nicht bereinigte Vorgänge erstellen, und die Erstellung von Operationen schlägt nie fehl, es sei denn, alle Operationsslots werden durch nicht bereinigte Vorgänge belegt. |
update | Erforderlich, um die Unterkomponente eines Schlüssels zu aktualisieren. |
use | Wird beim Erstellen einer Keymint-Operation überprüft, die das Schlüsselmaterial verwendet, z. B. zum Signieren, Ver-/Entschlüsseln. |
use_dev_id | Erforderlich beim Generieren von Geräteidentifizierungsinformationen, z. B. der Geräte-ID-Bescheinigung. |
Darüber hinaus haben wir eine Reihe nicht schlüsselspezifischer Keystore-Berechtigungen in der SELinux-Sicherheitsklasse keystore2
aufgeteilt:
Erlaubnis | Bedeutung |
---|---|
add_auth | Wird vom Authentifizierungsanbieter wie Gatekeeper oder BiometricsManager zum Hinzufügen von Authentifizierungstokens benötigt. |
clear_ns | Früher „clear_uid“ genannt, ermöglicht diese Berechtigung einem Nichtbesitzer eines Namespace, alle Schlüssel in diesem Namespace zu löschen. |
list | Wird vom System zum Aufzählen von Schlüsseln nach verschiedenen Eigenschaften benötigt, z. B. Eigentum oder Authentifizierungsbeschränkung. Diese Berechtigung ist für Aufrufer, die ihre eigenen Namespaces auflisten, nicht erforderlich. Dies wird durch die get_info Berechtigung abgedeckt. |
lock | Diese Berechtigung ermöglicht das Sperren des Keystores, d. h. das Entfernen des Hauptschlüssels, sodass an die Authentifizierung gebundene Schlüssel unbrauchbar und nicht erstellbar sind. |
reset | Mit dieser Berechtigung können Sie Keystore auf die Werkseinstellungen zurücksetzen und alle Schlüssel löschen, die für die Funktion des Android-Betriebssystems nicht unbedingt erforderlich sind. |
unlock | Diese Berechtigung ist erforderlich, um zu versuchen, den Hauptschlüssel für authentifizierungsgebundene Schlüssel zu entsperren. |
Die Verfügbarkeit einer vertrauenswürdigen Ausführungsumgebung in einem System on a Chip (SoC) bietet Android-Geräten die Möglichkeit, hardwaregestützte, starke Sicherheitsdienste für das Android-Betriebssystem, Plattformdienste und sogar Apps von Drittanbietern bereitzustellen. Entwickler, die Android-spezifische Erweiterungen suchen, sollten android.security.keystore aufrufen.
Vor Android 6.0 verfügte Android bereits über eine einfache, hardwaregestützte API für Kryptodienste, die durch die Versionen 0.2 und 0.3 des Keymaster Hardware Abstraction Layer (HAL) bereitgestellt wurde. Keystore stellte digitale Signatur- und Verifizierungsvorgänge sowie die Generierung und den Import asymmetrischer Signaturschlüsselpaare bereit. Dies ist bereits auf vielen Geräten implementiert, es gibt jedoch viele Sicherheitsziele, die mit nur einer Signatur-API nicht einfach erreicht werden können. Keystore in Android 6.0 hat die Keystore-API erweitert, um ein breiteres Spektrum an Funktionen bereitzustellen.
In Android 6.0 fügte Keystore symmetrische kryptografische Grundelemente , AES und HMAC sowie ein Zugriffskontrollsystem für hardwaregestützte Schlüssel hinzu. Zugriffskontrollen werden während der Schlüsselgenerierung festgelegt und für die Lebensdauer des Schlüssels durchgesetzt. Schlüssel können so eingeschränkt werden, dass sie nur nach Authentifizierung des Benutzers und nur für bestimmte Zwecke oder mit bestimmten kryptografischen Parametern verwendet werden können. Weitere Informationen finden Sie auf den Seiten Autorisierungs-Tags und -Funktionen .
Zusätzlich zur Erweiterung des Bereichs kryptografischer Grundelemente hat Keystore in Android 6.0 Folgendes hinzugefügt:
- Ein Nutzungskontrollschema, mit dem die Schlüsselnutzung eingeschränkt werden kann, um das Risiko einer Sicherheitsbeeinträchtigung aufgrund des Missbrauchs von Schlüsseln zu verringern
- Ein Zugriffskontrollschema, um die Beschränkung von Schlüsseln auf bestimmte Benutzer, Clients und einen definierten Zeitraum zu ermöglichen
In Android 7.0 fügte Keymaster 2 Unterstützung für Schlüsselnachweis und Versionsbindung hinzu. Die Schlüsselbescheinigung stellt öffentliche Schlüsselzertifikate bereit, die eine detaillierte Beschreibung des Schlüssels und seiner Zugriffskontrollen enthalten, um die Existenz des Schlüssels in sicherer Hardware und seine Konfiguration aus der Ferne überprüfbar zu machen.
Die Versionsbindung bindet Schlüssel an das Betriebssystem und die Patch-Level-Version. Dadurch wird sichergestellt, dass ein Angreifer, der eine Schwachstelle in einer alten Version des Systems oder der TEE-Software entdeckt, ein Gerät nicht auf die anfällige Version zurücksetzen und mit der neueren Version erstellte Schlüssel verwenden kann. Wenn außerdem ein Schlüssel mit einer bestimmten Version und Patch-Ebene auf einem Gerät verwendet wird, das auf eine neuere Version oder Patch-Ebene aktualisiert wurde, wird der Schlüssel aktualisiert, bevor er verwendet werden kann, und die vorherige Version des Schlüssels wird ungültig. Wenn das Gerät aktualisiert wird, „rasten“ die Tasten zusammen mit dem Gerät nach vorne, aber jede Rückstellung des Geräts auf eine frühere Version führt dazu, dass die Tasten unbrauchbar werden.
In Android 8.0 wechselte Keymaster 3 von der alten C-Struktur Hardware Abstraction Layer (HAL) zur C++-HAL-Schnittstelle, die aus einer Definition in der neuen Hardware Interface Definition Language (HIDL) generiert wurde. Im Rahmen der Änderung haben sich viele der Argumenttypen geändert, obwohl Typen und Methoden eine Eins-zu-eins-Entsprechung mit den alten Typen und den HAL-Strukturmethoden aufweisen. Weitere Einzelheiten finden Sie auf der Seite „Funktionen“ .
Zusätzlich zu dieser Schnittstellenüberarbeitung erweiterte Android 8.0 die Attestierungsfunktion von Keymaster 2 um die Unterstützung der ID-Attestierung . Die ID-Bescheinigung bietet einen begrenzten und optionalen Mechanismus zur starken Bescheinigung von Hardware-Identifikatoren, wie z. B. der Seriennummer des Geräts, dem Produktnamen und der Telefon-ID (IMEI/MEID). Um diesen Zusatz zu implementieren, hat Android 8.0 das ASN.1-Nachweisschema geändert, um einen ID-Nachweis hinzuzufügen. Keymaster-Implementierungen müssen einen sicheren Weg zum Abrufen der relevanten Datenelemente finden und einen Mechanismus zum sicheren und dauerhaften Deaktivieren der Funktion definieren.
Zu den Updates in Android 9 gehörten:
- Update auf Keymaster 4
- Unterstützung für eingebettete sichere Elemente
- Unterstützung für sicheren Schlüsselimport
- Unterstützung für 3DES-Verschlüsselung
- Änderungen an der Versionsbindung, sodass boot.img und system.img separat festgelegte Versionen haben, um unabhängige Updates zu ermöglichen
Glossar
Hier finden Sie einen kurzen Überblick über Keystore-Komponenten und ihre Beziehungen.
AndroidKeystore ist die Android Framework API und Komponente, die von Apps verwendet wird, um auf Keystore-Funktionen zuzugreifen. Es wird als Erweiterung der Standard-APIs der Java Cryptography Architecture implementiert und besteht aus Java-Code, der im eigenen Prozessraum der App ausgeführt wird. AndroidKeystore
erfüllt App-Anfragen zum Keystore-Verhalten, indem es sie an den Keystore-Daemon weiterleitet.
Der Keystore-Daemon ist ein Android-System-Daemon, der über eine Binder-API Zugriff auf alle Keystore-Funktionen bietet. Es ist für die Speicherung von „Schlüssel-Blobs“ verantwortlich, die das eigentliche geheime Schlüsselmaterial verschlüsselt enthalten, sodass Keystore sie speichern, aber nicht verwenden oder offenlegen kann.
keymasterd ist ein HIDL-Server, der Zugriff auf den Keymaster TA bietet. (Dieser Name ist nicht standardisiert und dient konzeptionellen Zwecken.)
Keymaster TA (vertrauenswürdige Anwendung) ist die Software, die in einem sicheren Kontext ausgeführt wird, meist in TrustZone auf einem ARM-SoC, die alle sicheren Keystore-Vorgänge bereitstellt, Zugriff auf das Rohschlüsselmaterial hat und alle Zugriffskontrollbedingungen für Schlüssel validiert , usw.
LockSettingsService ist die Android-Systemkomponente, die für die Benutzerauthentifizierung, sowohl Passwort als auch Fingerabdruck, verantwortlich ist. Es ist nicht Teil von Keystore, aber relevant, da viele Keystore-Schlüsselvorgänge eine Benutzerauthentifizierung erfordern. LockSettingsService
interagiert mit dem Gatekeeper TA und dem Fingerprint TA, um Authentifizierungstoken zu erhalten, die er dem Keystore-Daemon bereitstellt und die letztendlich von der Keymaster TA-Anwendung verwendet werden.
Gatekeeper TA (vertrauenswürdige Anwendung) ist eine weitere Komponente, die im sicheren Kontext ausgeführt wird und für die Authentifizierung von Benutzerkennwörtern und die Generierung von Authentifizierungstokens verantwortlich ist, mit denen dem Keymaster TA nachgewiesen werden kann, dass für einen bestimmten Benutzer zu einem bestimmten Zeitpunkt eine Authentifizierung durchgeführt wurde.
Fingerprint TA (vertrauenswürdige Anwendung) ist eine weitere Komponente, die im sicheren Kontext ausgeführt wird und für die Authentifizierung von Benutzerfingerabdrücken und die Generierung von Authentifizierungstokens verantwortlich ist, die dem Keymaster TA nachweisen, dass zu einem bestimmten Zeitpunkt eine Authentifizierung für einen bestimmten Benutzer durchgeführt wurde.
Die Architektur
Die Android Keystore API und der zugrunde liegende Keymaster HAL bieten einen grundlegenden, aber ausreichenden Satz kryptografischer Grundelemente, um die Implementierung von Protokollen mit zugriffskontrollierten, hardwaregestützten Schlüsseln zu ermöglichen.
Der Keymaster HAL ist eine vom OEM bereitgestellte, dynamisch ladbare Bibliothek, die vom Keystore-Dienst zur Bereitstellung hardwaregestützter kryptografischer Dienste verwendet wird. Um die Sicherheit zu gewährleisten, führen HAL-Implementierungen keine sensiblen Vorgänge im Benutzerbereich oder sogar im Kernelbereich aus. Sensible Vorgänge werden an einen sicheren Prozessor delegiert, der über eine Kernel-Schnittstelle erreicht wird. Die resultierende Architektur sieht folgendermaßen aus:

Abbildung 1. Zugriff auf Keymaster
Innerhalb eines Android-Geräts besteht der „Client“ des Keymaster HAL aus mehreren Schichten (z. B. App, Framework, Keystore-Daemon), die für die Zwecke dieses Dokuments jedoch ignoriert werden können. Dies bedeutet, dass die beschriebene Keymaster-HAL-API auf niedriger Ebene ist, von plattforminternen Komponenten verwendet wird und nicht für App-Entwickler verfügbar ist. Die übergeordnete API wird auf der Android-Entwicklerseite beschrieben.
Der Zweck des Keymaster HAL besteht nicht darin, die sicherheitsrelevanten Algorithmen zu implementieren, sondern nur darin, Anfragen an die sichere Welt zu marschieren und zu entmarshalieren. Das Wire-Format ist durch die Implementierung definiert.
Kompatibilität mit früheren Versionen
Der Keymaster 1 HAL ist völlig inkompatibel mit den zuvor veröffentlichten HALs, z. B. Keymaster 0.2 und 0.3. Um die Interoperabilität auf Geräten mit Android 5.0 und früher zu erleichtern, die mit den älteren Keymaster-HALs gestartet wurden, stellt Keystore einen Adapter bereit, der den Keymaster 1-HAL mit Aufrufen an die vorhandene Hardwarebibliothek implementiert. Das Ergebnis kann nicht den vollen Funktionsumfang des Keymaster 1 HAL bieten. Insbesondere werden nur RSA- und ECDSA-Algorithmen unterstützt und die gesamte Durchsetzung der Schlüsselautorisierung wird vom Adapter in der nicht sicheren Welt durchgeführt.
Keymaster 2 hat die HAL-Schnittstelle weiter vereinfacht, indem die get_supported_*
Methoden entfernt wurden und der Methode finish()
erlaubt wurde, Eingaben zu akzeptieren. Dies reduziert die Anzahl der Roundtrips zum TEE in Fällen, in denen die Eingabe auf einmal verfügbar ist, und vereinfacht die Implementierung der AEAD-Entschlüsselung.
In Android 8.0 wechselte Keymaster 3 von der C-Struktur-HAL im alten Stil zur C++-HAL-Schnittstelle, die aus einer Definition in der neuen Hardware Interface Definition Language (HIDL) generiert wurde. Eine HAL-Implementierung neuen Stils wird erstellt, indem die generierte IKeymasterDevice
Klasse in Unterklassen unterteilt und die rein virtuellen Methoden implementiert werden. Im Rahmen der Änderung haben sich viele der Argumenttypen geändert, obwohl Typen und Methoden eine Eins-zu-eins-Entsprechung mit den alten Typen und den HAL-Strukturmethoden aufweisen.
HIDL-Übersicht
Die Hardware Interface Definition Language (HIDL) bietet einen von der Implementierungssprache unabhängigen Mechanismus zum Spezifizieren von Hardwareschnittstellen. Die HIDL-Tools unterstützen derzeit die Generierung von C++- und Java-Schnittstellen. Es wird erwartet, dass die meisten TEE-Implementierer (Trusted Execution Environment) die C++-Tools bequemer finden werden, daher wird in diesem Dokument nur die C++-Darstellung behandelt.
HIDL-Schnittstellen bestehen aus einer Reihe von Methoden, ausgedrückt als:
methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);
Es gibt verschiedene vordefinierte Typen, und HALs können neue Aufzählungs- und Strukturtypen definieren. Weitere Einzelheiten zu HIDL finden Sie im Abschnitt „Referenz“ .
Eine Beispielmethode aus Keymaster 3 IKeymasterDevice.hal
ist:
generateKey(vec<KeyParameter> keyParams) generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
Dies entspricht dem Folgenden aus der keymaster2-HAL:
keymaster_error_t (*generate_key)( const struct keymaster2_device* dev, const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics);
In der HIDL-Version wird das dev
Argument entfernt, da es implizit ist. Das Argument params
ist keine Struktur mehr, die einen Zeiger enthält, der auf ein Array von key_parameter_t
Objekten verweist, sondern ein vec
(Vektor), der KeyParameter
Objekte enthält. Die Rückgabewerte werden in der „ generates
“-Klausel aufgelistet, einschließlich eines Vektors von uint8_t
Werten für den Schlüsselblob.
Die vom HIDL-Compiler generierte virtuelle C++-Methode lautet:
Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams, generateKey_cb _hidl_cb) override;
Dabei ist generateKey_cb
ein Funktionszeiger, der wie folgt definiert ist:
std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob, const KeyCharacteristics& keyCharacteristics)>
Das heißt, generateKey_cb
ist eine Funktion, die die in der „generate“-Klausel aufgeführten Rückgabewerte entgegennimmt. Die HAL-Implementierungsklasse überschreibt diese Methode generateKey
“ und ruft den Funktionszeiger generateKey_cb
auf, um das Ergebnis der Operation an den Aufrufer zurückzugeben. Beachten Sie, dass der Aufruf des Funktionszeigers synchron ist. Der Aufrufer ruft generateKey
auf und „ generateKey
ruft den bereitgestellten Funktionszeiger auf, der vollständig ausgeführt wird und die Kontrolle an die generateKey
-Implementierung zurückgibt, die dann an den Aufrufer zurückkehrt.
Ein detailliertes Beispiel finden Sie in der Standardimplementierung in hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp
. Die Standardimplementierung bietet Abwärtskompatibilität für Geräte mit keymaster0-, keymaster1- oder keymaster2-HALS im alten Stil.
Zugangskontrolle
Die grundlegendste Regel der Keystore-Zugriffskontrolle besteht darin, dass jede App über einen eigenen Namespace verfügt. Aber für jede Regel gibt es eine Ausnahme. Keystore verfügt über einige hartcodierte Karten, die bestimmten Systemkomponenten den Zugriff auf bestimmte andere Namespaces ermöglichen. Dies ist ein sehr einfaches Instrument, da es einer Komponente die volle Kontrolle über einen anderen Namespace gibt. Und dann ist da noch die Frage der Herstellerkomponenten als Clients für Keystore. Wir haben derzeit keine Möglichkeit, einen Namensraum für Anbieterkomponenten, beispielsweise WPA-Supplicant, einzurichten.
Um Anbieterkomponenten zu berücksichtigen und die Zugriffskontrolle ohne hartcodierte Ausnahmen zu verallgemeinern, führt Keystore 2.0 Domänen und SELinux-Namespaces ein.
Keystore-Domänen
Mit Keystore-Domänen können wir Namespaces von UIDs entkoppeln. Clients, die auf einen Schlüssel im Keystore zugreifen, müssen die Domäne, den Namensraum und den Alias angeben, auf die sie zugreifen möchten. Anhand dieses Tupels und der Identität des Anrufers können wir bestimmen, auf welchen Schlüssel der Anrufer zugreifen möchte und ob er über die entsprechenden Berechtigungen verfügt.
Wir führen fünf Domänenparameter ein, die steuern, wie auf Schlüssel zugegriffen werden kann. Sie steuern die Semantik des Namespace-Parameters des Schlüsseldeskriptors und die Art und Weise, wie die Zugriffskontrolle durchgeführt wird.
-
DOMAIN_APP
: Die App-Domäne deckt das Legacy-Verhalten ab. Die Java Keystore SPI verwendet diese Domäne standardmäßig. Bei Verwendung dieser Domäne wird das Namespace-Argument ignoriert und stattdessen die UID des Aufrufers verwendet. Der Zugriff auf diese Domäne wird durch das Keystore-Label der Klassekeystore_key
in der SELinux-Richtlinie gesteuert. -
DOMAIN_SELINUX
: Diese Domäne gibt an, dass der Namespace eine Bezeichnung in der SELinux-Richtlinie hat. Der Namespace-Parameter wird nachgeschlagen und in einen Zielkontext übersetzt, und es wird eine Berechtigungsprüfung für den aufrufenden SELinux-Kontext für die Klassekeystore_key
durchgeführt. Wenn die Berechtigung für den angegebenen Vorgang eingerichtet wurde, wird das vollständige Tupel für die Schlüsselsuche verwendet. -
DOMAIN_GRANT
: The grant domain indicates that the namespace parameter is a grant identifier. The alias parameter is ignored. SELinux checks are performed when the grant is created. Further access control only checks if the caller UID matches the grantees UID of the requested grant. -
DOMAIN_KEY_ID
: This domain indicates that the namespace parameter is a unique key id. The key itself may have been created withDOMAIN_APP
orDOMAIN_SELINUX
. The permission check is performed after thedomain
and thenamespace
have been loaded from the key database in the same way as if the blob was loaded by the domain, namespace, and alias tuple. The rationale for the key id domain is continuity. When accessing a key by alias, subsequent calls may operate on different keys, because a new key may have been generated or imported and bound to this alias. The key id, however, never changes. So when using a key by key id after it has been loaded from the Keystore database using the alias once, one can be certain that it is the same key as long as the key id still exists. This functionality is not exposed to app developers. Instead, it is used within the Android Keystore SPI to provide a more consistent experience even when used concurrently in an unsafe way. -
DOMAIN_BLOB
: The blob domain indicates that the caller manages the blob by itself. This is used for clients that need to access the Keystore before the data partition is mounted. The key blob is included in theblob
field of the key descriptor.
Using the SELinux domain, we can give vendor components access to very specific Keystore namespaces which can be shared by system components such as the settings dialog.
SELinux policy for keystore_key
Namespace labels are configured using the keystore2_key_context
file.
Each line in these files maps a numeric namespace id to an SELinux label. For example,
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share keystore keys. 102 u:object_r:wifi_key:s0
After having set up a new key namespace in this way, we can give access to it by adding an appropriate policy. For example, to allow wpa_supplicant
to get and use keys in the new namespace we would add the following line to hal_wifi_supplicant.te
:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
After setting up the new namespace, AndroidKeyStore can be used almost as usual. The only difference is that the namespace ID must be specified. For loading and importing keys from and into Keystore, the namespace id is specified using the AndroidKeyStoreLoadStoreParameter
. For example,
import android.security.keystore2.AndroidKeyStoreLoadStoreParameter; import java.security.KeyStore; KeyStore keystore = KeyStore.getInstance("AndroidKeyStore"); keystore.load(new AndroidKeyStoreLoadStoreParameter(102));
To generate a key in a given namespace, the namespace id must be given using KeyGenParameterSpec.Builder#setNamespace():
import android.security.keystore.KeyGenParameterSpec; KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder(); specBuilder.setNamespace(102);
The following context files may be used to configure Keystore 2.0 SELinux namespaces. Each partition has a different reserved range of 10,000 namespace ids to avoid collisions.
Partition | Range | Config files |
---|---|---|
System | 0 ... 9,999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts |
Extended System | 10,000 ... 19,999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts |
Product | 20,000 ... 29,999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts |
Vendor | 30,000 ... 39,999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts |
The client requests the key by requesting the SELinux domain and the desired virtual namespace, in this case "wifi_key"
, by its numeric id.
Above that, the following namespaces have been defined. If they replace special rules, the following table indicates the UID they used to correspond to.
Namespace ID | SEPolicy Label | UID | Description |
---|---|---|---|
0 | su_key | N/A | Super user key. Only used for testing on userdebug and eng builds. Not relevant on user builds. |
1 | shell_key | N/A | Namespace available to shell. Mostly used for testing, but can be used on user builds as well from the command line. |
100 | vold_key | N/A | Intended for use by vold. |
101 | odsing_key | N/A | Used by the on-device signing daemon. |
102 | wifi_key | AID_WIFI(1010) | Used by Android's Wifi sybsystem including wpa_supplicant. |
120 | resume_on_reboot_key | AID_SYSTEM(1000) | Used by Android's system server to support resume on reboot. |
Access Vectors
The SELinux class keystore_key
has aged quite a bit and some of the permissions, such as verify
or sign
have lost their meaning. Here is the new set of permissions, keystore2_key
, that Keystore 2.0 will enforce.
Permission | Meaning |
---|---|
delete | Checked when removing keys from Keystore. |
get_info | Checked when a key's metadata is requested. |
grant | The caller needs this permission to create a grant to the key in the target context. |
manage_blob | The caller may use DOMAIN_BLOB on the given SELinux namespace, thereby managing blobs by itself. This is specifically useful for vold. |
rebind | This permission controls if an alias may be rebound to a new key. This is required for insertion and implies that the previously bound key will be deleted. It is basically an insert permission, but it captures the semantic of keystore better. |
req_forced_op | Clients with this permission may create unpruneable operations, and operation creation never fails unless all operation slots are taken by unpruneable operations. |
update | Required to update the subcomponent of a key. |
use | Checked when creating a Keymint operation that uses the key material, eg, for signing, en/decryption. |
use_dev_id | Required when generating device identifying information, such as device id attestation. |
Additionally, we split out a set of non key specific keystore permissions in the SELinux security class keystore2
:
Permission | Meaning |
---|---|
add_auth | Required by authentication provider such as Gatekeeper or BiometricsManager for adding auth tokens. |
clear_ns | Formerly clear_uid, this permission allows a non owner of a namespace to delete all keys in that namespace. |
list | Required by the system for enumerating keys by various properties, such as ownership or auth boundedness. This permission is not required by callers enumerating their own namespaces. This is covered by the get_info permission. |
lock | This permission allows to lock Keystore, that is, evict the master key, such that auth bound keys become unusable and uncreatable. |
reset | This permission allows to reset Keystore to factory default, deleting all keys that are not vital to the functioning of the Android OS. |
unlock | This permission is required to attempt to unlock the master key for auth bound keys. |