diff options
author | Danny Lin <danny@kdrag0n.dev> | 2021-10-11 20:00:44 -0700 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2023-08-08 02:08:48 +0800 |
commit | c6f3d568baaea91b9df56b38b9b2b64d9af75851 (patch) | |
tree | 6c9cb6dbdc2dd510f108848bcb7f6eb146bc96e2 | |
parent | 555e3a9a903d0f841617e649338b948ca6991d78 (diff) |
keystore: Block key attestation for SafetyNet
SafetyNet (part of Google Play Services) opportunistically uses
hardware-backed key attestation via KeyStore as a strong integrity
check. This causes SafetyNet to fail on custom ROMs because the verified
boot key and bootloader unlock state can be detected from attestation
certificates.
As a workaround, we can take advantage of the fact that SafetyNet's
usage of key attestation is opportunistic (i.e. falls back to basic
integrity checks if it fails) and prevent it from getting the
attestation certificate chain from KeyStore. This is done by checking
the stack for DroidGuard, which is the codename for SafetyNet, and
pretending that the device doesn't support key attestation.
Key attestation has only been blocked for SafetyNet specifically, as
Google Play Services and other apps have many valid reasons to use it.
For example, it appears to be involved in Google's mobile security key
ferature.
Change-Id: I5146439d47f42dc6231cb45c4dab9f61540056f6
-rw-r--r-- | core/java/com/android/internal/gmscompat/AttestationHooks.java | 16 | ||||
-rw-r--r-- | keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java | 3 |
2 files changed, 19 insertions, 0 deletions
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java index 4c7335236cd6..64e29fd3a826 100644 --- a/core/java/com/android/internal/gmscompat/AttestationHooks.java +++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java @@ -21,6 +21,7 @@ import android.os.Build; import android.util.Log; import java.lang.reflect.Field; +import java.util.Arrays; /** @hide */ public final class AttestationHooks { @@ -29,6 +30,8 @@ public final class AttestationHooks { private static final String PACKAGE_GMS = "com.google.android.gms"; private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable"; + private static volatile boolean sIsGms = false; + private AttestationHooks() { } private static void setBuildField(String key, Object value) { @@ -52,10 +55,23 @@ public final class AttestationHooks { String processName = Application.getProcessName(); if (PACKAGE_GMS.equals(packageName) && PROCESS_UNSTABLE.equals(processName)) { + sIsGms = true; setBuildField("DEVICE", "redfin"); setBuildField("PRODUCT", "redfin"); setBuildField("MODEL", "Pixel 5"); setBuildField("FINGERPRINT", "google/redfin/redfin:13/TQ3A.230605.011/10161073:user/release-keys"); } } + + private static boolean isCallerSafetyNet() { + return Arrays.stream(Thread.currentThread().getStackTrace()) + .anyMatch(elem -> elem.getClassName().contains("DroidGuard")); + } + + public static void onEngineGetCertificateChain() { + // Check stack for SafetyNet + if (sIsGms && isCallerSafetyNet()) { + throw new UnsupportedOperationException(); + } + } } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java index 33411e1ec5b9..133a4094d434 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java @@ -42,6 +42,7 @@ import android.system.keystore2.ResponseCode; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.gmscompat.AttestationHooks; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -164,6 +165,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { @Override public Certificate[] engineGetCertificateChain(String alias) { + AttestationHooks.onEngineGetCertificateChain(); + KeyEntryResponse response = getKeyMetadata(alias); if (response == null || response.metadata.certificate == null) { |