fix(shim): resolve attest key by nspace

The probe in duck-detector's TimingSideChannelProbe chain calls
generateSigningKey with a KEY_ID-domain attestation key reference
where alias is null. KMSLI.kt:498 fed that null alias into the
non-null String param of KeyIdentifier, triggering an NPE that
the outer runCatching wraps into a ServiceSpecificException(-49).
Any SSE crossing the binder boundary carries the Parcel.read/
createException(OrNull) stack frames, which the detector's
TeeReportReducer at line 2635-2641 matches verbatim to emit
"Captured private binder exception during timing skip".

Branch on the alias before constructing KeyIdentifier: when
alias is present, retain the existing isAttestationKey lookup;
when null (Domain::KEY_ID), scan attestationKeys for a matching
uid + nspace via generatedKeys. Mirrors AOSP keystore2's own
dispatch in database.rs (Domain::APP by alias, Domain::KEY_ID
by key id).
This commit is contained in:
Enginex0
2026-05-19 13:32:54 +01:00
parent 59836e143c
commit d7dc5e0b63
@@ -495,7 +495,8 @@ class KeyMintSecurityLevelInterceptor(
ConfigurationManager.shouldGenerate(callingUid) || ConfigurationManager.shouldGenerate(callingUid) ||
(ConfigurationManager.shouldPatch(callingUid) && isAttestKeyRequest) || (ConfigurationManager.shouldPatch(callingUid) && isAttestKeyRequest) ||
(attestationKey != null && (attestationKey != null &&
isAttestationKey(KeyIdentifier(callingUid, attestationKey.alias))) (attestationKey.alias?.let { isAttestationKey(KeyIdentifier(callingUid, it)) }
?: attestationKeys.any { kid -> kid.uid == callingUid && generatedKeys[kid]?.nspace == attestationKey.nspace }))
val isAuto = ConfigurationManager.isAutoMode(callingUid) val isAuto = ConfigurationManager.isAutoMode(callingUid)