Auf dieser Seite finden Sie zusätzliche Details und Richtlinien für die Implementierung der KeyMint-Hardwareabstraktionsschicht (Hardware Abstraction Layer, HAL). Die primäre Dokumentation für das HAL ist die AIDL-Schnittstellenspezifikation.
API-Missbrauch
Anrufer können KeyMint-Schlüssel mit Autorisierungen erstellen, die als API-Parameter gültig sind, die resultierenden Schlüssel jedoch unsicher oder unbrauchbar machen. KeyMint-Implementierungen müssen in solchen Fällen nicht fehlschlagen oder eine Diagnose ausgeben. Die Verwendung zu kleiner Schlüssel, die Angabe irrelevanter Eingabeparameter, die Wiederverwendung von IVs oder Nounces, die Generierung von Schlüsseln ohne Verwendungszweck (daher nutzlos) und Ähnliches sollten nicht von Implementierungen diagnostiziert werden.
Es liegt in der Verantwortung von Apps, dem Framework und dem Android-Schlüsselspeicher, dafür zu sorgen, dass die Aufrufe von KeyMint-Modulen sinnvoll und nützlich sind.
addRngEntropy-Einstiegspunkt
Der Einstiegspunkt addRngEntropy
fügt dem Pool, der von der KeyMint-Implementierung zum Generieren von Zufallszahlen für Schlüssel und Initialisierungsvektoren verwendet wird, vom Aufrufer bereitgestellte Entropie hinzu.
KeyMint-Implementierungen müssen die bereitgestellte Entropie sicher in ihren Pool einfügen. Dieser muss auch intern generierte Entropie von einem Hardware-Zufallszahlengenerator enthalten. Die Mischung sollte so erfolgen, dass ein Angreifer, der die vollständige Kontrolle über die von addRngEntropy
bereitgestellten oder die von der Hardware generierten Bits (aber nicht beide) hat, keinen wesentlichen Vorteil bei der Vorhersage der aus dem Entropiepool generierten Bits hat.
Wichtige Merkmale
Jeder der Mechanismen (generateKey
, importKey
und importWrappedKey
), mit denen KeyMint-Schlüssel erstellt werden, gibt die Merkmale des neu erstellten Schlüssels zurück, die entsprechend in die Sicherheitsstufen unterteilt sind, die jedes Merkmal erzwingen. Die zurückgegebenen Merkmale enthalten alle Parameter, die für die Schlüsselerstellung angegeben wurden, mit Ausnahme von Tag::APPLICATION_ID
und Tag::APPLICATION_DATA
.
Wenn diese Tags in den Schlüsselparametern enthalten sind, werden sie aus den zurückgegebenen Attributen entfernt, sodass ihre Werte nicht durch Untersuchen des zurückgegebenen Keyblobs ermittelt werden können. Sie sind jedoch kryptografisch an den Keyblob gebunden. Wenn also bei der Verwendung des Schlüssels nicht die richtigen Werte angegeben werden, schlägt die Verwendung fehl. Ebenso ist Tag::ROOT_OF_TRUST
kryptografisch an den Schlüssel gebunden, kann aber beim Erstellen oder Importieren des Schlüssels nicht angegeben werden und wird nie zurückgegeben.
Zusätzlich zu den bereitgestellten Tags fügt die KeyMint-Implementierung auch Tag::ORIGIN
hinzu, das angibt, wie der Schlüssel erstellt wurde (KeyOrigin::GENERATED
, KeyOrigin::IMPORTED
oder KeyOrigin::SECURELY_IMPORTED
).
Rollback-Sperre
Die Rollback-Resistenz wird durch Tag::ROLLBACK_RESISTANCE
angegeben. Sie bedeutet, dass ein mit deleteKey
oder deleteAllKeys
gelöschter Schlüssel von der sicheren Hardware nie wieder verwendet werden kann.
KeyMint-Implementierungen geben generiertes oder importiertes Schlüsselmaterial in verschlüsselter und authentifizierter Form als Keyblob an den Aufrufer zurück. Wenn Keystore den Keyblob löscht, ist der Schlüssel weg. Ein Angreifer, der das Schlüsselmaterial zuvor abgerufen hat, könnte es jedoch möglicherweise auf dem Gerät wiederherstellen.
Ein Schlüssel ist rollbacksicher, wenn die sichere Hardware dafür sorgt, dass gelöschte Schlüssel später nicht wiederhergestellt werden können. Dies geschieht in der Regel, indem zusätzliche Schlüsselmetadaten an einem vertrauenswürdigen Ort gespeichert werden, der nicht von einem Angreifer manipuliert werden kann. Auf Mobilgeräten wird dafür in der Regel der Replay Protected Memory Block (RPMB) verwendet. Da die Anzahl der Schlüssel, die erstellt werden können, im Wesentlichen unbegrenzt ist und der für die Rollback-Resistenz verwendete vertrauenswürdige Speicher möglicherweise begrenzt ist, kann die Implementierung Anfragen zum Erstellen von Rollback-resistenten Schlüsseln ablehnen, wenn der Speicher voll ist.
anfangen
Der Einstiegspunkt begin()
startet einen kryptografischen Vorgang mit dem angegebenen Schlüssel, für den angegebenen Zweck und mit den angegebenen Parametern (falls zutreffend). Es wird ein neues IKeyMintOperation
-Binder-Objekt zurückgegeben, das zum Abschließen des Vorgangs verwendet wird. Außerdem wird ein Challenge-Wert zurückgegeben, der als Teil des Authentifizierungstokens bei authentifizierten Vorgängen verwendet wird.
Eine KeyMint-Implementierung unterstützt mindestens 16 gleichzeitige Vorgänge. Keystore verwendet bis zu 15 Schlüssel. Einer bleibt für vold
zur Verschlüsselung von Passwörtern übrig. Wenn im Keystore 15 Vorgänge laufen (begin()
wurde aufgerufen, aber finish
oder abort
nicht) und eine Anfrage für einen 16. Vorgang eingeht, wird abort()
für den am wenigsten zuletzt verwendeten Vorgang aufgerufen, um die Anzahl der aktiven Vorgänge auf 14 zu reduzieren, bevor begin()
aufgerufen wird, um den neu angeforderten Vorgang zu starten.
Wenn Tag::APPLICATION_ID
oder Tag::APPLICATION_DATA
bei der Schlüsselgenerierung oder beim Import angegeben wurden, müssen Aufrufe von begin()
diese Tags mit den ursprünglich angegebenen Werten im params
-Argument für diese Methode enthalten.
Fehlerbehandlung
Wenn eine Methode für ein IKeyMintOperation
einen anderen Fehlercode als ErrorCode::OK
zurückgibt, wird der Vorgang abgebrochen und das Binder-Objekt des Vorgangs wird ungültig. Bei jeder zukünftigen Verwendung des Objekts wird ErrorCode::INVALID_OPERATION_HANDLE
zurückgegeben.
Autorisierung erzwingen
Die Erzwingung der Schlüsselautorisierung erfolgt hauptsächlich in begin()
. Die einzige Ausnahme ist der Fall, in dem der Schlüssel einen oder mehrere Tag::USER_SECURE_ID
-Werte, aber keinen Tag::AUTH_TIMEOUT
-Wert hat.
In diesem Fall ist für den Schlüssel eine Autorisierung pro Vorgang erforderlich und die Methoden update()
oder finish()
erhalten ein Autorisierungstoken im Argument authToken
. Damit das Token gültig ist, muss die KeyMint-Implementierung:
- Überprüft die HMAC-Signatur des Authentifizierungstokens.
- Prüft, ob das Token eine sichere Nutzer-ID enthält, die mit einer ID übereinstimmt, die dem Schlüssel zugeordnet ist.
- Prüft, ob der Autorisierungstyp des Tokens mit dem
Tag::USER_AUTH_TYPE
des Schlüssels übereinstimmt. - Prüft, ob das Token den Challenge-Wert für den aktuellen Vorgang im Feld „challenge“ enthält.
Wenn diese Bedingungen nicht erfüllt sind, gibt KeyMint ErrorCode::KEY_USER_NOT_AUTHENTICATED
zurück.
Der Aufrufer stellt das Authentifizierungstoken für jeden Aufruf von update()
und finish()
bereit. Das Token kann nur einmal validiert werden.