Auf dieser Seite finden Sie zusätzliche Details und Richtlinien für Implementierer der KeyMint-Hardwareabstraktionsschicht (HAL). Die primäre Dokumentation für die HAL ist die AIDL Schnittstellenspezifikation.
Missbrauch der API
Aufrufer 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 Nonces, die Generierung von Schlüsseln ohne Zweck (und damit nutzlos) und Ähnliches sollten nicht von Implementierungen diagnostiziert werden.
Es liegt in der Verantwortung von Apps, dem Framework und Android Keystore, dafür zu sorgen, dass die Aufrufe an KeyMint-Module sinnvoll und nützlich sind.
Einstiegspunkt addRngEntropy
Der Einstiegspunkt addRngEntropy fügt dem Pool, der von der KeyMint-Implementierung zum Generieren von Zufallszahlen für Schlüssel und IVs verwendet wird, vom Aufrufer bereitgestellte Entropie hinzu.
KeyMint-Implementierungen müssen die bereitgestellte Entropie sicher in ihren Pool mischen, der auch intern generierte Entropie aus einem Hardware-Zufallszahlengenerator enthalten muss. Das Mischen sollte so erfolgen, dass ein Angreifer, der die vollständige Kontrolle über die von addRngEntropy bereitgestellten Bits oder die von der Hardware generierten Bits (aber nicht beide) hat, keinen erheblichen Vorteil bei der Vorhersage der aus dem Entropiepool generierten Bits hat.
Wichtige Merkmale
Jeder der Mechanismen (generateKey, importKey und importWrappedKey), die KeyMint-Schlüssel erstellen, 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 umfassen alle für die Schlüsselerstellung angegebenen Parameter, 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 Merkmalen entfernt, damit ihre Werte nicht durch Untersuchen des zurückgegebenen Keyblobs ermittelt werden können. Sie sind jedoch kryptografisch an den Keyblob gebunden, sodass die Verwendung fehlschlägt, wenn bei der Verwendung des Schlüssels nicht die richtigen Werte angegeben werden. Ebenso ist Tag::ROOT_OF_TRUST kryptografisch an den Schlüssel gebunden, kann aber bei der Schlüsselerstellung oder beim Import nicht angegeben werden und wird nie zurückgegeben.
Zusätzlich zu den bereitgestellten Tags fügt die KeyMint-Implementierung auch Tag::ORIGIN hinzu, das die Art angibt, wie der Schlüssel erstellt wurde (KeyOrigin::GENERATED, KeyOrigin::IMPORTED oder KeyOrigin::SECURELY_IMPORTED).
Rollback-Sperre
Die Rollback-Sperre wird durch Tag::ROLLBACK_RESISTANCE angegeben. Das bedeutet, dass der Schlüssel nach dem Löschen mit deleteKey oder deleteAllKeys von der sicheren Hardware nie wieder verwendet werden kann.
KeyMint-Implementierungen geben generiertes oder importiertes Schlüsselmaterial als Keyblob an den Aufrufer zurück, eine verschlüsselte und authentifizierte Form. 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 rollback-sicher, wenn die sichere Hardware dafür sorgt, dass gelöschte Schlüssel später nicht wiederhergestellt werden können. Dies geschieht in der Regel durch Speichern zusätzlicher Schlüsselmetadaten an einem vertrauenswürdigen Ort, der nicht von einem Angreifer manipuliert werden kann. Auf Mobilgeräten wird dafür in der Regel der speichergeschützte Speicherblock (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-Sperre verwendete vertrauenswürdige Speicher möglicherweise begrenzt ist, kann die Implementierung Anfragen zum Erstellen von rollback-sicheren 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). Er gibt ein neues IKeyMintOperation-Binder-Objekt zurück, das zum Abschließen des Vorgangs verwendet wird. Außerdem wird ein Challenge-Wert zurückgegeben, der als Teil des Authentifizierungstokens in authentifizierten Vorgängen verwendet wird.
Eine KeyMint-Implementierung unterstützt mindestens 16 gleichzeitige Vorgänge. Keystore verwendet bis zu 15, sodass einer für vold zur Passwortverschlüsselung übrig bleibt. Wenn Keystore 15 Vorgänge ausführt (begin() wurde
aufgerufen, aber finish oder abort nicht
aufgerufen) und eine Anfrage zum Starten eines 16. Vorgangs erhält, ruft er
abort() für den zuletzt verwendeten Vorgang auf, um die Anzahl der
aktiven Vorgänge auf 14 zu reduzieren, bevor er begin() aufruft, um den
neu angeforderten Vorgang zu starten.
Wenn bei der Schlüsselerstellung oder beim Import Tag::APPLICATION_ID oder Tag::APPLICATION_DATA angegeben wurden, müssen Aufrufe von begin() diese Tags mit den ursprünglich angegebenen Werten im Argument params dieser 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 hat und keinen Tag::AUTH_TIMEOUT-Wert.
In diesem Fall erfordert der Schlüssel eine Autorisierung pro Vorgang und die Methoden update() oder finish() erhalten ein Authentifizierungstoken im Argument authToken. Damit das Token gültig ist, führt die KeyMint-Implementierung Folgendes aus:
- Überprüft die HMAC-Signatur des Authentifizierungstokens.
- Prüft, ob das Token eine sichere Nutzer-ID enthält, die mit einem Schlüssel verknüpft ist.
- Prüft, ob der Authentifizierungstyp des Tokens mit dem
Tag::USER_AUTH_TYPEdes Schlüssels übereinstimmt. - Prüft, ob das Token den Challenge-Wert für den aktuellen Vorgang im Challenge-Feld 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. Die Implementierung kann das Token nur einmal validieren.