Auf dieser Seite finden Sie weitere Informationen und Richtlinien für die Implementierung der KeyMint-Hardwareabstraktionsschicht (HAL). Die primäre Dokumentation für die HAL ist die AIDL-Schnittstellenspezifikation.
API-Missbrauch
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 IV- oder Nonce-Werten, die Generierung von Schlüsseln ohne Zweck (und daher nutzlos) und ähnliches sollten von Implementierungen nicht erkannt werden.
Es liegt in der Verantwortung der Apps, des Frameworks und des Android Keystore, dafür zu sorgen, dass die Aufrufe von KeyMint-Modulen sinnvoll und nützlich sind.
Einstiegspunkt für addRngEntropy
Der addRngEntropy
-Eintragspunkt fügt dem Pool, der von der KeyMint-Implementierung zum Generieren von Zufallszahlen für Schlüssel und IV verwendet wird, vom Aufrufer bereitgestellte Entropie hinzu.
KeyMint-Implementierungen müssen die bereitgestellte Entropie sicher in ihren Pool einmischen, der auch intern generierte Entropie von einem Hardware-Zufallszahlengenerator enthalten muss. Die Mischung sollte so erfolgen, dass ein Angreifer, der entweder die von addRngEntropy
bereitgestellten Bits oder die hardwaregenerierten Bits vollständig kontrollieren kann (aber nicht beides), keinen signifikanten Vorteil bei der Vorhersage der aus dem Entropiepool generierten Bits hat.
Hauptmerkmale
Jeder der Mechanismen (generateKey
, importKey
und importWrappedKey
), mit denen KeyMint-Schlüssel erstellt werden, gibt die Eigenschaften des neu erstellten Schlüssels zurück, die entsprechend in die Sicherheitsebenen unterteilt sind, die für jede Eigenschaft gelten. 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, sodass ihre Werte nicht durch Prüfung des zurückgegebenen Schlüsselblobs ermittelt werden können. Sie sind jedoch kryptografisch an den Schlüssel-Blob 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 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
angezeigt. Das bedeutet, dass ein Schlüssel, der mit deleteKey
oder deleteAllKeys
gelöscht wurde, durch die sichere Hardware so verändert wird, dass er nie wieder verwendet werden kann.
KeyMint-Implementierungen geben generiertes oder importiertes Schlüsselmaterial als Key-Blob, eine verschlüsselte und authentifizierte Form, an den Aufrufer zurück. Wenn der Keystore den Keyblob löscht, ist der Schlüssel nicht mehr verfügbar. Ein Angreifer, der es zuvor geschafft hat, das Schlüsselmaterial abzurufen, kann 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. Dazu werden in der Regel zusätzliche Schlüsselmetadaten an einem sicheren Ort gespeichert, der nicht von einem Angreifer manipuliert werden kann. Auf Mobilgeräten wird dafür in der Regel der Mechanismus „Replay Protected Memory Blocks“ (RPMB) verwendet. Da die Anzahl der Schlüssel, die erstellt werden können, im Grunde unbegrenzt ist und der für die Rollback-Resistenz verwendete vertrauenswürdige Speicher möglicherweise begrenzt ist, kann die Implementierung bei Anfragen zum Erstellen von Rollback-resistenten Schlüsseln fehlschlagen, wenn der Speicher voll ist.
anfangen
Der begin()
-Einstiegspunkt beginnt einen kryptografischen Vorgang mit dem angegebenen Schlüssel, für den angegebenen Zweck und mit den angegebenen Parametern (falls zutreffend). Es gibt ein neues IKeyMintOperation
-Binder-Objekt zurück, das zum Ausführen des Vorgangs verwendet wird. Außerdem wird ein Challenge-Wert zurückgegeben, der bei authentifizierten Vorgängen als Teil des Authentifizierungstokens verwendet wird.
Eine KeyMint-Implementierung unterstützt mindestens 16 gleichzeitige Vorgänge. Der Keystore verwendet bis zu 15 Schlüssel, sodass einer für vold
zur Passwortverschlüsselung übrig bleibt. Wenn im Keystore 15 Vorgänge ausgeführt werden (begin()
wurde aufgerufen, aber finish
oder abort
nicht) und eine Anfrage zum Starten eines 16. Vorgangs eingeht, wird abort()
für den am wenigsten 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 dem Import angegeben wurden, müssen Aufrufe von begin()
diese Tags mit den ursprünglich angegebenen Werten im params
-Argument dieser Methode enthalten.
Fehlerbehandlung
Wenn eine Methode auf einem IKeyMintOperation
einen anderen Fehlercode als ErrorCode::OK
zurückgibt, wird der Vorgang abgebrochen und das Binder-Objekt für den Vorgang ungültig. Bei jeder weiteren Verwendung des Objekts wird ErrorCode::INVALID_OPERATION_HANDLE
zurückgegeben.
Autorisierung erzwingen
Die Schlüsselautorisierung wird hauptsächlich in begin()
erzwungen. Eine Ausnahme ist der Fall, dass 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
. Um sicherzustellen, dass das Token gültig ist, führt die KeyMint-Implementierung folgende Schritte aus:
- Prüft die HMAC-Signatur im Authentifizierungstoken.
- Prüft, ob das Token eine sichere Nutzer-ID enthält, die mit der mit dem Schlüssel verknüpften übereinstimmt.
- Prüft, ob der Authentifizierungstyp des Tokens mit dem
Tag::USER_AUTH_TYPE
des Schlüssels übereinstimmt. - Prüft, ob das Token im Feld „challenge“ den Wert für die aktuelle Operation 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 überprüfen.