fix(interception): strip INCLUDE_UNIQUE_ID instead of rejecting when permission missing#27
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughKeyMintSecurityLevelInterceptor's key generation now gracefully degrades when ChangesUnique ID Attestation Fallback
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates the KeyMint security level interceptor to avoid failing generateKey when apps request INCLUDE_UNIQUE_ID without the required permissions, improving compatibility (notably with Google Wallet / Play Integrity flows).
Changes:
- Make
params/parsedParamsmutable so the request can be modified in-flight. - Replace permission-denied behavior for
Tag.INCLUDE_UNIQUE_IDwith silent stripping of the tag when permissions are missing. - Expand inline documentation explaining the rationale and upstream AOSP behavior.
Comments suppressed due to low confidence (1)
app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt:1
isAttestKeyRequestis derived fromparsedParamsbeforeparamscan be modified (andparsedParamsis later rebuilt after strippingINCLUDE_UNIQUE_ID). This can leaveisAttestKeyRequestinconsistent with the final parsed parameters. ComputeisAttestKeyRequestafter any potential parameter mutation (or recompute it whenparsedParamsis reassigned).
package org.matrix.TEESimulator.interception.keystore.shim
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ssing permission
The INCLUDE_UNIQUE_ID gate in handleGenerateKey (introduced as part of the
PR157 AOSP-compliance work) returns PERMISSION_DENIED when the caller
holds neither SELinux gen_unique_id nor REQUEST_UNIQUE_ID_ATTESTATION.
This breaks Google Wallet card binding on real devices: Wallet's
generateKey carries INCLUDE_UNIQUE_ID without holding the permission, so
its attestation key request is rejected and Wallet surfaces the failure
as "this phone does not meet the security requirements for Google
Wallet". Symptoms reported by users: clearing GMS data only helps for a
few seconds before the state regresses; no card can be added.
Naive removal of the gate is not safe: AttestationBuilder honours
`includeUniqueId == true` by computing an HMAC-SHA256 unique_id and
embedding it in the attestation extension. With the gate gone, GMS
attestation flows that include the tag end up with a unique_id in the
extension that Play Integrity flags as inconsistent for the caller,
turning all three integrity verdicts red.
The fix here splits the difference: when the permission check fails,
silently strip the INCLUDE_UNIQUE_ID tag from the KeyParameter array
(and re-parse `parsedParams`) instead of rejecting the request. The key
generates normally, AttestationBuilder takes the
`else { ByteArray(0) }` branch, and the resulting attestation simply
omits the unique_id field — matching pre-PR157 behaviour, where the
tag effectively had no effect.
Verified on a device that previously failed Wallet binding on the
PR157 baseline:
- Play Integrity: BASIC + DEVICE + STRONG all pass.
- Google Wallet: card binding completes successfully.
- Calls that DO hold the permission are unaffected (still emit
unique_id as before).
The rest of the PR157 compliance work (CALLER_NONCE handling,
AuthorizeCreate ordering, USAGE_COUNT_LIMIT counters, effectiveParams
merging) is preserved.
2382e87 to
4d81809
Compare
|
Thanks. This actually fixed my usage of Google Wallet. |
Summary
The
INCLUDE_UNIQUE_IDpermission gate inhandleGenerateKeyrejectsthe entire
generateKeycall withPERMISSION_DENIEDwhen the callerholds neither SELinux
gen_unique_idnorREQUEST_UNIQUE_ID_ATTESTATION. This breaks Google Wallet on realdevices: Wallet's attestation key request carries
INCLUDE_UNIQUE_IDwithout the permission, so the request is rejected and Wallet shows
"this phone does not meet the security requirements for Google Wallet".
Clearing GMS data only helps for a few seconds.
Why this fix instead of removing the gate
Naive removal regresses Play Integrity to three-red.
AttestationBuilderhonours
includeUniqueId == trueby computing an HMAC-SHA256unique_idand embedding it in the attestation extension. With thegate removed, GMS attestation flows pick the tag through and the
extension ends up with a
unique_idthat the integrity server flags asinconsistent for the caller.
Approach
When the permission check fails, silently strip
INCLUDE_UNIQUE_IDfromthe
KeyParameter[](and re-parseparsedParams) instead of rejecting.The key generates normally,
AttestationBuilderfalls through toelse { ByteArray(0) }, and the resulting attestation simply omits theunique_idfield. This matches pre-PR157 behaviour, where the tag hadno effect.
Calls that do hold the permission are unaffected —
unique_idisstill emitted as before.
Verification
Tested on a device that previously failed Wallet binding on the PR157
baseline:
USAGE_COUNT_LIMIT counters, effectiveParams merging) untouched.
Bisect
The regression was bisected commit-by-commit between
v5.0-138andv5.1-153; isolated to commit 8eda2d8("feat(interception): add AOSP authorize_create enforcement and wire
format fixes"); within that commit, narrowed to the
INCLUDE_UNIQUE_IDgate specifically.Summary by CodeRabbit