Enforce 128-byte limit for attestation challenge#70
Enforce 128-byte limit for attestation challenge#70JingMatrix merged 1 commit intoJingMatrix:mainfrom
Conversation
98ec7de to
b5c0ae2
Compare
|
@Stillhard Could you try this commit, please? |
Wonderful result 😘 Thank you @XiaoTong6666 |
|
I cannot reproduce the detection on my device, which version of the detector were you using? Moreover, I think that we don't need to write an exception manually. Hard-coding exception codes is a bad practice, and not elegant. We can simply raise an error inside the |
I was using this version of the detector: |
Got it, thanks for the clarification. I've updated the code and force-pushed. It now just throws inside the |
|
@XiaoTong6666 What should return by your detector ? In my device, it is always |
The detection is based on the incorrect behavior of software emulation (Force Generation Mode) when handling oversized challenges (>128 bytes): real TEE hardware naturally rejects them, while the old simulator accepted them. Which is exactly what this PR fixes ! |
|
How do you detect it? This was my question. Till now, I haven't seen any detector real detects it on my device. If certain device, probably like my Pixel 6, can actually accept long challenge, then this PR is introducing a detection point for these devices. |
|
Regarding the reference implementation, the logic in attestation_record.cpp explicitly enforces this limit: bool is_valid_attestation_challenge(const keymaster_blob_t& attestation_challenge) {
// TODO(171864369): Limit apps targeting >= API 30 to attestations in the range of
// [0, 128] bytes.
return (attestation_challenge.data_length <= kMaximumAttestationChallengeLength);
}(kMaximumAttestationChallengeLength is defined as 128 in the same file). |
|
As said several time, I cannot get detected by these mentioned detectors. I am asking for a reliable PoC to really detect it. |
|
Yes, the detection logic is fully open source. You can see the checkAttestationChallenge implementation here: |
|
Please add this to (Note the |
|
I see, it is a design flaw of these detectors. |
|
The 128-byte limit is a hard constraint of the KeyMint/Keymaster HAL enforced during record construction, so it applies to all Key Attestation flows (both standard factory attestation and Android 12+ app-provisioned attestation) regardless of the signing key used.
|
Throws IllegalArgumentException if the challenge exceeds 128 bytes, per Android specs. Also fixes a duplicate assignment typo in KeystoreInterceptor. Reference: https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder#setAttestationChallenge(byte[])
|
The implementation looks perfect. Moving the check to CertificateGenerator is a much cleaner solution as it covers both KeyStore and KeyMint paths automatically. Thanks for merging and fixing the duplicate assignment typo! |
|
@XiaoTong6666 You may create another pull-request when you feel confident. Thanks for the contribution. |






This commit aligns the simulator's behavior with the Android Keymaster/KeyMint specification by enforcing a maximum length of 128 bytes for the attestation challenge.
Previously, the simulator accepted attestation challenges of arbitrary length during
generateKey. This behavior differed from real implementations and allowed detection tools to identify whether the current TEE / KeyMint / Keymaster environment was emulated or tampered with by intentionally sending an oversized challenge (e.g., > 128 bytes) and observing that it was accepted instead of rejected.The implementation now validates the size of the
TAG_ATTESTATION_CHALLENGEparameter. If the challenge exceeds the limit, the transaction is intercepted, and aServiceSpecificExceptionis constructed manually via Binder (using theEX_SERVICE_SPECIFICheader) to return theINVALID_INPUT_LENGTH(-21) error code. This matches the error code and Binder-visible behavior defined by the KeyMint specification.这个 commit 是通过将 attestation challenge 的最大长度限制为 128 字节,让模拟的行为更加符合 Keymaster / KeyMint 的规范。
在此之前,模拟器在 generateKey 过程中会接受任意长度的 attestation challenge。这种行为与真实实现不一致,导致一些检测工具可以通过刻意发送超长 challenge(比如超过 128 字节),并观察是否被接受,来判断当前 TEE/ KeyMint / Keymaster 是否模拟被篡改。
现在的实现会对 TAG_ATTESTATION_CHALLENGE 的长度进行检查。如果 challenge 超过限制,请求会被直接拦截,并通过 Binder 手动构造一个 ServiceSpecificException(使用 EX_SERVICE_SPECIFIC 头),返回 INVALID_INPUT_LENGTH(-21)错误码,这样可以保证返回的错误码和 Binder 层可观察到的行为与 Keymaster / KeyMint 规范保持一致
See AOSP source for the length constraint and error definition:
https://cs.android.com/android/platform/superproject/main/+/main:system/keymaster/android_keymaster/android_keymaster.cpp;l=330
https://cs.android.com/android/platform/superproject/main/+/main:system/keymaster/km_openssl/attestation_record.cpp;l=257
https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl;l=48