mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2025-01-24 14:21:30 -05:00
you want it, you got it!
now compile it yourself. Signed-off-by: Tavi <tavi@divested.dev>
This commit is contained in:
parent
f5d06ea9aa
commit
4f8cfc8a41
511
Patches/LineageOS-16.0/android_frameworks_base/snet-16.patch
Normal file
511
Patches/LineageOS-16.0/android_frameworks_base/snet-16.patch
Normal file
@ -0,0 +1,511 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||
enforcement
|
||||
|
||||
As of September 2, Google is enforcing SafetyNet's previously
|
||||
opportunistic hardware-backed attestation based on device information.
|
||||
Append a space to the device model name in order to avoid such
|
||||
enforcement.
|
||||
|
||||
Also contains:
|
||||
Spoof build fingerprint for Google Play Services
|
||||
|
||||
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||
matches that of the device's stock OS, which has passed CTS testing.
|
||||
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||
|
||||
We used to set the real system build fingerprint to the stock one, but
|
||||
Android relies on each build having a unique fingerprint in order to
|
||||
clear the correct caches and update persistent state for system changes.
|
||||
On devices that no longer receive updates from the OEM, the build
|
||||
fingerprint never changes and Android doesn't account for updates
|
||||
correctly, which causes issues when updating without wiping data.
|
||||
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||
|
||||
Corresponding vendor commit:
|
||||
"Only use stock build fingerprint for Google Play Services"
|
||||
|
||||
NB: This code is under the gmscompat package, but it does not depend on
|
||||
any code from gmscompat.
|
||||
|
||||
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||
|
||||
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||
use the Build field spoofing code it added for model
|
||||
|
||||
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||
---
|
||||
core/java/android/app/Instrumentation.java | 4 ++
|
||||
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||
2 files changed, 63 insertions(+)
|
||||
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
|
||||
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||
index d4385549da02..61e4176392f7 100644
|
||||
--- a/core/java/android/app/Instrumentation.java
|
||||
+++ b/core/java/android/app/Instrumentation.java
|
||||
@@ -53,6 +53,8 @@ import android.view.Window;
|
||||
|
||||
import com.android.internal.content.ReferrerIntent;
|
||||
|
||||
+import com.android.internal.gmscompat.AttestationHooks;
|
||||
+
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -1119,6 +1121,7 @@ public class Instrumentation {
|
||||
Application app = getFactory(context.getPackageName())
|
||||
.instantiateApplication(cl, className);
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -1136,6 +1139,7 @@ public class Instrumentation {
|
||||
ClassNotFoundException {
|
||||
Application app = (Application)clazz.newInstance();
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
new file mode 100644
|
||||
index 000000000000..621156eb84b9
|
||||
--- /dev/null
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2021 The Android Open Source Project
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+
|
||||
+package com.android.internal.gmscompat;
|
||||
+
|
||||
+import android.app.Application;
|
||||
+import android.os.Build;
|
||||
+import android.os.SystemProperties;
|
||||
+import android.util.Log;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+
|
||||
+/** @hide */
|
||||
+public final class AttestationHooks {
|
||||
+ private static final String TAG = "GmsCompat/Attestation";
|
||||
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+
|
||||
+ private AttestationHooks() { }
|
||||
+
|
||||
+ private static void setBuildField(String key, String value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void spoofBuildGms() {
|
||||
+ // Alter model name to avoid hardware attestation enforcement
|
||||
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ }
|
||||
+
|
||||
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||
Subject: [PATCH 2/8] 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
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||
.../security/keystore/AndroidKeyStoreSpi.java | 4 ++++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 621156eb84b9..fe12dfe02a9f 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
+import java.util.Arrays;
|
||||
|
||||
/** @hide */
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
|
||||
+ private static volatile boolean sIsGms = false;
|
||||
+
|
||||
private AttestationHooks() { }
|
||||
|
||||
private static void setBuildField(String key, String value) {
|
||||
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ 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/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
index 4c007cb70ba2..7dcd79197aa5 100644
|
||||
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
@@ -30,6 +30,8 @@ import android.security.keystore.SecureKeyImportUnavailableException;
|
||||
import android.security.keystore.WrappedKeyEntry;
|
||||
import android.util.Log;
|
||||
|
||||
+import com.android.internal.gmscompat.AttestationHooks;
|
||||
+
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -104,6 +106,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||
|
||||
@Override
|
||||
public Certificate[] engineGetCertificateChain(String alias) {
|
||||
+ AttestationHooks.onEngineGetCertificateChain();
|
||||
+
|
||||
if (alias == null) {
|
||||
throw new NullPointerException("alias == null");
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||
>=33
|
||||
|
||||
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||
Setting it to 32 allows for software attestation and passing CTS.
|
||||
|
||||
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index fe12dfe02a9f..f512adc3985b 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||
}
|
||||
}
|
||||
|
||||
+ private static void setVersionField(String key, Integer value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name to avoid hardware attestation enforcement
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
+ }
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||
|
||||
The unstable process is where SafetyNet attestation actually runs, so
|
||||
we only need to spoof the model in that process. Leaving other processes
|
||||
fixes various issues caused by model detection and flag provisioning,
|
||||
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||
weather and settings on Android 12, and more.
|
||||
|
||||
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index f512adc3985b..c1021dd2eb22 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
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;
|
||||
|
||||
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||
aswell
|
||||
|
||||
Play Store is used for the new Play Integrity API, extend the hack
|
||||
to it aswell
|
||||
|
||||
Test: Device Integrity and Basic Integrity passes.
|
||||
|
||||
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index c1021dd2eb22..6a4aab000fe0 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||
|
||||
private static volatile boolean sIsGms = false;
|
||||
+ private static volatile boolean sIsFinsky = false;
|
||||
|
||||
private AttestationHooks() { }
|
||||
|
||||
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
+
|
||||
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
+ sIsFinsky = true;
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||
if (sIsGms && isCallerSafetyNet()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
+
|
||||
+ // Check stack for PlayIntegrity
|
||||
+ if (sIsFinsky) {
|
||||
+ throw new UnsupportedOperationException();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||
|
||||
Google seems to have patched the KM block to Play Store in record time,
|
||||
but is still not enforced for anything under android N.
|
||||
|
||||
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||
anymore, however the KM block is still needed.
|
||||
|
||||
Test: Run Play Intregrity Attestation
|
||||
|
||||
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
- // Alter model name to avoid hardware attestation enforcement
|
||||
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||
|
||||
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
sIsFinsky = true;
|
||||
- spoofBuildGms();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||
|
||||
The logic behind CTS and Play Integrity has been updated today it now
|
||||
checks the product and model names against the fingerprint and if
|
||||
they do not match the CTS profile will fail.
|
||||
|
||||
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||
for key attestation blocking for debugging.
|
||||
|
||||
Test: Boot, check for CTS and Play Integrity
|
||||
|
||||
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
- setBuildField("MODEL", Build.MODEL + " ");
|
||||
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
- }
|
||||
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
+ setBuildField("PRODUCT", "marlin");
|
||||
+ setBuildField("DEVICE", "marlin");
|
||||
+ setBuildField("MODEL", "Pixel XL");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||
+ return sIsGms && 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();
|
||||
- }
|
||||
-
|
||||
- // Check stack for PlayIntegrity
|
||||
- if (sIsFinsky) {
|
||||
+ // Check stack for SafetyNet or Play Integrity
|
||||
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Davide Garberi <dade.garberi@gmail.com>
|
||||
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||
|
||||
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index b10cb04cb4f3..04a536d8073d 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
- setBuildField("PRODUCT", "marlin");
|
||||
- setBuildField("DEVICE", "marlin");
|
||||
- setBuildField("MODEL", "Pixel XL");
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
+ setBuildField("DEVICE", "bullhead");
|
||||
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||
+ setBuildField("MODEL", "Nexus 5X");
|
||||
+ setBuildField("PRODUCT", "bullhead");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
59
Patches/LineageOS-16.0/android_system_core/snet-16.patch
Normal file
59
Patches/LineageOS-16.0/android_system_core/snet-16.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||
|
||||
Google's SafetyNet integrity checks will check the values of these
|
||||
properties when performing basic attestation. Setting fake values helps
|
||||
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||
|
||||
Note that these properties need to be set very early, before parsing the
|
||||
kernel command-line, as they are read-only properties that the bootloader
|
||||
sets using androidboot kernel arguments. The bootloader's real values
|
||||
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||
software because the verified boot chain is broken in that case.
|
||||
|
||||
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||
|
||||
- Also don't set these in recovery
|
||||
|
||||
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||
---
|
||||
init/property_service.cpp | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||
index f47c93596..6c404de62 100644
|
||||
--- a/init/property_service.cpp
|
||||
+++ b/init/property_service.cpp
|
||||
@@ -101,6 +101,15 @@ struct PropertyAuditData {
|
||||
const char* name;
|
||||
};
|
||||
|
||||
+static void SetSafetyNetProps() {
|
||||
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||
+ InitPropertySet("ro.warranty_bit", "0");
|
||||
+}
|
||||
+
|
||||
void property_init() {
|
||||
mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH);
|
||||
CreateSerializedPropertyInfo();
|
||||
@@ -110,6 +119,14 @@ void property_init() {
|
||||
if (!property_info_area.LoadDefaultPath()) {
|
||||
LOG(FATAL) << "Failed to load serialized property info file";
|
||||
}
|
||||
+
|
||||
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||
+ // these properties are read-only and will be set to invalid values with
|
||||
+ // androidboot cmdline arguments.
|
||||
+ if (!IsRecoveryMode()) {
|
||||
+ SetSafetyNetProps();
|
||||
+ }
|
||||
}
|
||||
static bool CheckMacPerms(const std::string& name, const char* target_context,
|
||||
const char* source_context, const ucred& cr) {
|
511
Patches/LineageOS-17.1/android_frameworks_base/snet-17.patch
Normal file
511
Patches/LineageOS-17.1/android_frameworks_base/snet-17.patch
Normal file
@ -0,0 +1,511 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||
enforcement
|
||||
|
||||
As of September 2, Google is enforcing SafetyNet's previously
|
||||
opportunistic hardware-backed attestation based on device information.
|
||||
Append a space to the device model name in order to avoid such
|
||||
enforcement.
|
||||
|
||||
Also contains:
|
||||
Spoof build fingerprint for Google Play Services
|
||||
|
||||
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||
matches that of the device's stock OS, which has passed CTS testing.
|
||||
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||
|
||||
We used to set the real system build fingerprint to the stock one, but
|
||||
Android relies on each build having a unique fingerprint in order to
|
||||
clear the correct caches and update persistent state for system changes.
|
||||
On devices that no longer receive updates from the OEM, the build
|
||||
fingerprint never changes and Android doesn't account for updates
|
||||
correctly, which causes issues when updating without wiping data.
|
||||
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||
|
||||
Corresponding vendor commit:
|
||||
"Only use stock build fingerprint for Google Play Services"
|
||||
|
||||
NB: This code is under the gmscompat package, but it does not depend on
|
||||
any code from gmscompat.
|
||||
|
||||
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||
|
||||
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||
use the Build field spoofing code it added for model
|
||||
|
||||
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||
---
|
||||
core/java/android/app/Instrumentation.java | 4 ++
|
||||
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||
2 files changed, 63 insertions(+)
|
||||
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
|
||||
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||
index 9720e9f47f83..e19f3fc4db85 100644
|
||||
--- a/core/java/android/app/Instrumentation.java
|
||||
+++ b/core/java/android/app/Instrumentation.java
|
||||
@@ -57,6 +57,8 @@ import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.internal.content.ReferrerIntent;
|
||||
|
||||
+import com.android.internal.gmscompat.AttestationHooks;
|
||||
+
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -1154,6 +1156,7 @@ public class Instrumentation {
|
||||
Application app = getFactory(context.getPackageName())
|
||||
.instantiateApplication(cl, className);
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -1171,6 +1174,7 @@ public class Instrumentation {
|
||||
ClassNotFoundException {
|
||||
Application app = (Application)clazz.newInstance();
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
new file mode 100644
|
||||
index 000000000000..621156eb84b9
|
||||
--- /dev/null
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2021 The Android Open Source Project
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+
|
||||
+package com.android.internal.gmscompat;
|
||||
+
|
||||
+import android.app.Application;
|
||||
+import android.os.Build;
|
||||
+import android.os.SystemProperties;
|
||||
+import android.util.Log;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+
|
||||
+/** @hide */
|
||||
+public final class AttestationHooks {
|
||||
+ private static final String TAG = "GmsCompat/Attestation";
|
||||
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+
|
||||
+ private AttestationHooks() { }
|
||||
+
|
||||
+ private static void setBuildField(String key, String value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void spoofBuildGms() {
|
||||
+ // Alter model name to avoid hardware attestation enforcement
|
||||
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ }
|
||||
+
|
||||
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||
Subject: [PATCH 2/8] 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
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||
.../security/keystore/AndroidKeyStoreSpi.java | 4 ++++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 621156eb84b9..fe12dfe02a9f 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
+import java.util.Arrays;
|
||||
|
||||
/** @hide */
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
|
||||
+ private static volatile boolean sIsGms = false;
|
||||
+
|
||||
private AttestationHooks() { }
|
||||
|
||||
private static void setBuildField(String key, String value) {
|
||||
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ 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/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
index 51c42520ccc9..b77ddc711492 100644
|
||||
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
@@ -30,6 +30,8 @@ import android.security.keystore.SecureKeyImportUnavailableException;
|
||||
import android.security.keystore.WrappedKeyEntry;
|
||||
import android.util.Log;
|
||||
|
||||
+import com.android.internal.gmscompat.AttestationHooks;
|
||||
+
|
||||
import libcore.util.EmptyArray;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -113,6 +115,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||
|
||||
@Override
|
||||
public Certificate[] engineGetCertificateChain(String alias) {
|
||||
+ AttestationHooks.onEngineGetCertificateChain();
|
||||
+
|
||||
if (alias == null) {
|
||||
throw new NullPointerException("alias == null");
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||
>=33
|
||||
|
||||
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||
Setting it to 32 allows for software attestation and passing CTS.
|
||||
|
||||
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index fe12dfe02a9f..f512adc3985b 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||
}
|
||||
}
|
||||
|
||||
+ private static void setVersionField(String key, Integer value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name to avoid hardware attestation enforcement
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
+ }
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||
|
||||
The unstable process is where SafetyNet attestation actually runs, so
|
||||
we only need to spoof the model in that process. Leaving other processes
|
||||
fixes various issues caused by model detection and flag provisioning,
|
||||
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||
weather and settings on Android 12, and more.
|
||||
|
||||
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index f512adc3985b..c1021dd2eb22 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
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;
|
||||
|
||||
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||
aswell
|
||||
|
||||
Play Store is used for the new Play Integrity API, extend the hack
|
||||
to it aswell
|
||||
|
||||
Test: Device Integrity and Basic Integrity passes.
|
||||
|
||||
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index c1021dd2eb22..6a4aab000fe0 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||
|
||||
private static volatile boolean sIsGms = false;
|
||||
+ private static volatile boolean sIsFinsky = false;
|
||||
|
||||
private AttestationHooks() { }
|
||||
|
||||
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
+
|
||||
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
+ sIsFinsky = true;
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||
if (sIsGms && isCallerSafetyNet()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
+
|
||||
+ // Check stack for PlayIntegrity
|
||||
+ if (sIsFinsky) {
|
||||
+ throw new UnsupportedOperationException();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||
|
||||
Google seems to have patched the KM block to Play Store in record time,
|
||||
but is still not enforced for anything under android N.
|
||||
|
||||
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||
anymore, however the KM block is still needed.
|
||||
|
||||
Test: Run Play Intregrity Attestation
|
||||
|
||||
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
- // Alter model name to avoid hardware attestation enforcement
|
||||
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||
|
||||
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
sIsFinsky = true;
|
||||
- spoofBuildGms();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||
|
||||
The logic behind CTS and Play Integrity has been updated today it now
|
||||
checks the product and model names against the fingerprint and if
|
||||
they do not match the CTS profile will fail.
|
||||
|
||||
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||
for key attestation blocking for debugging.
|
||||
|
||||
Test: Boot, check for CTS and Play Integrity
|
||||
|
||||
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
- setBuildField("MODEL", Build.MODEL + " ");
|
||||
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
- }
|
||||
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
+ setBuildField("PRODUCT", "marlin");
|
||||
+ setBuildField("DEVICE", "marlin");
|
||||
+ setBuildField("MODEL", "Pixel XL");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||
+ return sIsGms && 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();
|
||||
- }
|
||||
-
|
||||
- // Check stack for PlayIntegrity
|
||||
- if (sIsFinsky) {
|
||||
+ // Check stack for SafetyNet or Play Integrity
|
||||
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Davide Garberi <dade.garberi@gmail.com>
|
||||
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||
|
||||
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index b10cb04cb4f3..04a536d8073d 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
- setBuildField("PRODUCT", "marlin");
|
||||
- setBuildField("DEVICE", "marlin");
|
||||
- setBuildField("MODEL", "Pixel XL");
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
+ setBuildField("DEVICE", "bullhead");
|
||||
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||
+ setBuildField("MODEL", "Nexus 5X");
|
||||
+ setBuildField("PRODUCT", "bullhead");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
59
Patches/LineageOS-17.1/android_system_core/snet-17.patch
Normal file
59
Patches/LineageOS-17.1/android_system_core/snet-17.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||
|
||||
Google's SafetyNet integrity checks will check the values of these
|
||||
properties when performing basic attestation. Setting fake values helps
|
||||
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||
|
||||
Note that these properties need to be set very early, before parsing the
|
||||
kernel command-line, as they are read-only properties that the bootloader
|
||||
sets using androidboot kernel arguments. The bootloader's real values
|
||||
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||
software because the verified boot chain is broken in that case.
|
||||
|
||||
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||
|
||||
- Also don't set these in recovery
|
||||
|
||||
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||
---
|
||||
init/property_service.cpp | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||
index 65e9cda1c..7be56d0db 100644
|
||||
--- a/init/property_service.cpp
|
||||
+++ b/init/property_service.cpp
|
||||
@@ -117,6 +117,15 @@ static int PropertyAuditCallback(void* data, security_class_t /*cls*/, char* buf
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void SetSafetyNetProps() {
|
||||
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||
+ InitPropertySet("ro.warranty_bit", "0");
|
||||
+}
|
||||
+
|
||||
void property_init() {
|
||||
selinux_callback cb;
|
||||
cb.func_audit = PropertyAuditCallback;
|
||||
@@ -130,6 +139,14 @@ void property_init() {
|
||||
if (!property_info_area.LoadDefaultPath()) {
|
||||
LOG(FATAL) << "Failed to load serialized property info file";
|
||||
}
|
||||
+
|
||||
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||
+ // these properties are read-only and will be set to invalid values with
|
||||
+ // androidboot cmdline arguments.
|
||||
+ if (!IsRecoveryMode()) {
|
||||
+ SetSafetyNetProps();
|
||||
+ }
|
||||
}
|
||||
|
||||
bool CanReadProperty(const std::string& source_context, const std::string& name) {
|
511
Patches/LineageOS-18.1/android_frameworks_base/snet-18.patch
Normal file
511
Patches/LineageOS-18.1/android_frameworks_base/snet-18.patch
Normal file
@ -0,0 +1,511 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||
enforcement
|
||||
|
||||
As of September 2, Google is enforcing SafetyNet's previously
|
||||
opportunistic hardware-backed attestation based on device information.
|
||||
Append a space to the device model name in order to avoid such
|
||||
enforcement.
|
||||
|
||||
Also contains:
|
||||
Spoof build fingerprint for Google Play Services
|
||||
|
||||
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||
matches that of the device's stock OS, which has passed CTS testing.
|
||||
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||
|
||||
We used to set the real system build fingerprint to the stock one, but
|
||||
Android relies on each build having a unique fingerprint in order to
|
||||
clear the correct caches and update persistent state for system changes.
|
||||
On devices that no longer receive updates from the OEM, the build
|
||||
fingerprint never changes and Android doesn't account for updates
|
||||
correctly, which causes issues when updating without wiping data.
|
||||
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||
|
||||
Corresponding vendor commit:
|
||||
"Only use stock build fingerprint for Google Play Services"
|
||||
|
||||
NB: This code is under the gmscompat package, but it does not depend on
|
||||
any code from gmscompat.
|
||||
|
||||
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||
|
||||
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||
use the Build field spoofing code it added for model
|
||||
|
||||
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||
---
|
||||
core/java/android/app/Instrumentation.java | 4 ++
|
||||
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||
2 files changed, 63 insertions(+)
|
||||
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
|
||||
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||
index 721525d9af9d..09dcad811d4d 100644
|
||||
--- a/core/java/android/app/Instrumentation.java
|
||||
+++ b/core/java/android/app/Instrumentation.java
|
||||
@@ -57,6 +57,8 @@ import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.internal.content.ReferrerIntent;
|
||||
|
||||
+import com.android.internal.gmscompat.AttestationHooks;
|
||||
+
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -1157,6 +1159,7 @@ public class Instrumentation {
|
||||
Application app = getFactory(context.getPackageName())
|
||||
.instantiateApplication(cl, className);
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -1174,6 +1177,7 @@ public class Instrumentation {
|
||||
ClassNotFoundException {
|
||||
Application app = (Application)clazz.newInstance();
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
new file mode 100644
|
||||
index 000000000000..621156eb84b9
|
||||
--- /dev/null
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2021 The Android Open Source Project
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+
|
||||
+package com.android.internal.gmscompat;
|
||||
+
|
||||
+import android.app.Application;
|
||||
+import android.os.Build;
|
||||
+import android.os.SystemProperties;
|
||||
+import android.util.Log;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+
|
||||
+/** @hide */
|
||||
+public final class AttestationHooks {
|
||||
+ private static final String TAG = "GmsCompat/Attestation";
|
||||
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+
|
||||
+ private AttestationHooks() { }
|
||||
+
|
||||
+ private static void setBuildField(String key, String value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void spoofBuildGms() {
|
||||
+ // Alter model name to avoid hardware attestation enforcement
|
||||
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ }
|
||||
+
|
||||
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||
Subject: [PATCH 2/8] 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
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||
.../security/keystore/AndroidKeyStoreSpi.java | 4 ++++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 621156eb84b9..fe12dfe02a9f 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
+import java.util.Arrays;
|
||||
|
||||
/** @hide */
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
|
||||
+ private static volatile boolean sIsGms = false;
|
||||
+
|
||||
private AttestationHooks() { }
|
||||
|
||||
private static void setBuildField(String key, String value) {
|
||||
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ 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/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
index 51c42520ccc9..b77ddc711492 100644
|
||||
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||
@@ -30,6 +30,8 @@ import android.security.keystore.SecureKeyImportUnavailableException;
|
||||
import android.security.keystore.WrappedKeyEntry;
|
||||
import android.util.Log;
|
||||
|
||||
+import com.android.internal.gmscompat.AttestationHooks;
|
||||
+
|
||||
import libcore.util.EmptyArray;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -113,6 +115,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||
|
||||
@Override
|
||||
public Certificate[] engineGetCertificateChain(String alias) {
|
||||
+ AttestationHooks.onEngineGetCertificateChain();
|
||||
+
|
||||
if (alias == null) {
|
||||
throw new NullPointerException("alias == null");
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||
>=33
|
||||
|
||||
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||
Setting it to 32 allows for software attestation and passing CTS.
|
||||
|
||||
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index fe12dfe02a9f..f512adc3985b 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||
}
|
||||
}
|
||||
|
||||
+ private static void setVersionField(String key, Integer value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name to avoid hardware attestation enforcement
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
+ }
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||
|
||||
The unstable process is where SafetyNet attestation actually runs, so
|
||||
we only need to spoof the model in that process. Leaving other processes
|
||||
fixes various issues caused by model detection and flag provisioning,
|
||||
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||
weather and settings on Android 12, and more.
|
||||
|
||||
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index f512adc3985b..c1021dd2eb22 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
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;
|
||||
|
||||
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||
aswell
|
||||
|
||||
Play Store is used for the new Play Integrity API, extend the hack
|
||||
to it aswell
|
||||
|
||||
Test: Device Integrity and Basic Integrity passes.
|
||||
|
||||
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index c1021dd2eb22..6a4aab000fe0 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||
|
||||
private static volatile boolean sIsGms = false;
|
||||
+ private static volatile boolean sIsFinsky = false;
|
||||
|
||||
private AttestationHooks() { }
|
||||
|
||||
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
+
|
||||
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
+ sIsFinsky = true;
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||
if (sIsGms && isCallerSafetyNet()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
+
|
||||
+ // Check stack for PlayIntegrity
|
||||
+ if (sIsFinsky) {
|
||||
+ throw new UnsupportedOperationException();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||
|
||||
Google seems to have patched the KM block to Play Store in record time,
|
||||
but is still not enforced for anything under android N.
|
||||
|
||||
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||
anymore, however the KM block is still needed.
|
||||
|
||||
Test: Run Play Intregrity Attestation
|
||||
|
||||
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
- // Alter model name to avoid hardware attestation enforcement
|
||||
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||
|
||||
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
sIsFinsky = true;
|
||||
- spoofBuildGms();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||
|
||||
The logic behind CTS and Play Integrity has been updated today it now
|
||||
checks the product and model names against the fingerprint and if
|
||||
they do not match the CTS profile will fail.
|
||||
|
||||
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||
for key attestation blocking for debugging.
|
||||
|
||||
Test: Boot, check for CTS and Play Integrity
|
||||
|
||||
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
- setBuildField("MODEL", Build.MODEL + " ");
|
||||
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
- }
|
||||
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
+ setBuildField("PRODUCT", "marlin");
|
||||
+ setBuildField("DEVICE", "marlin");
|
||||
+ setBuildField("MODEL", "Pixel XL");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||
+ return sIsGms && 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();
|
||||
- }
|
||||
-
|
||||
- // Check stack for PlayIntegrity
|
||||
- if (sIsFinsky) {
|
||||
+ // Check stack for SafetyNet or Play Integrity
|
||||
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Davide Garberi <dade.garberi@gmail.com>
|
||||
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||
|
||||
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index b10cb04cb4f3..04a536d8073d 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
- setBuildField("PRODUCT", "marlin");
|
||||
- setBuildField("DEVICE", "marlin");
|
||||
- setBuildField("MODEL", "Pixel XL");
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
+ setBuildField("DEVICE", "bullhead");
|
||||
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||
+ setBuildField("MODEL", "Nexus 5X");
|
||||
+ setBuildField("PRODUCT", "bullhead");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
59
Patches/LineageOS-18.1/android_system_core/snet-18.patch
Normal file
59
Patches/LineageOS-18.1/android_system_core/snet-18.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||
|
||||
Google's SafetyNet integrity checks will check the values of these
|
||||
properties when performing basic attestation. Setting fake values helps
|
||||
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||
|
||||
Note that these properties need to be set very early, before parsing the
|
||||
kernel command-line, as they are read-only properties that the bootloader
|
||||
sets using androidboot kernel arguments. The bootloader's real values
|
||||
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||
software because the verified boot chain is broken in that case.
|
||||
|
||||
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||
|
||||
- Also don't set these in recovery
|
||||
|
||||
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||
---
|
||||
init/property_service.cpp | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||
index 42dd5afcb..a2c7c2db6 100644
|
||||
--- a/init/property_service.cpp
|
||||
+++ b/init/property_service.cpp
|
||||
@@ -1064,6 +1064,15 @@ static void ProcessKernelCmdline() {
|
||||
}
|
||||
}
|
||||
|
||||
+static void SetSafetyNetProps() {
|
||||
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||
+ InitPropertySet("ro.warranty_bit", "0");
|
||||
+}
|
||||
+
|
||||
void PropertyInit() {
|
||||
selinux_callback cb;
|
||||
cb.func_audit = PropertyAuditCallback;
|
||||
@@ -1078,6 +1087,14 @@ void PropertyInit() {
|
||||
LOG(FATAL) << "Failed to load serialized property info file";
|
||||
}
|
||||
|
||||
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||
+ // these properties are read-only and will be set to invalid values with
|
||||
+ // androidboot cmdline arguments.
|
||||
+ if (!IsRecoveryMode()) {
|
||||
+ SetSafetyNetProps();
|
||||
+ }
|
||||
+
|
||||
// If arguments are passed both on the command line and in DT,
|
||||
// properties set in DT always have priority over the command-line ones.
|
||||
ProcessKernelDt();
|
510
Patches/LineageOS-19.1/android_frameworks_base/snet-19.patch
Normal file
510
Patches/LineageOS-19.1/android_frameworks_base/snet-19.patch
Normal file
@ -0,0 +1,510 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||
enforcement
|
||||
|
||||
As of September 2, Google is enforcing SafetyNet's previously
|
||||
opportunistic hardware-backed attestation based on device information.
|
||||
Append a space to the device model name in order to avoid such
|
||||
enforcement.
|
||||
|
||||
Also contains:
|
||||
Spoof build fingerprint for Google Play Services
|
||||
|
||||
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||
matches that of the device's stock OS, which has passed CTS testing.
|
||||
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||
|
||||
We used to set the real system build fingerprint to the stock one, but
|
||||
Android relies on each build having a unique fingerprint in order to
|
||||
clear the correct caches and update persistent state for system changes.
|
||||
On devices that no longer receive updates from the OEM, the build
|
||||
fingerprint never changes and Android doesn't account for updates
|
||||
correctly, which causes issues when updating without wiping data.
|
||||
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||
|
||||
Corresponding vendor commit:
|
||||
"Only use stock build fingerprint for Google Play Services"
|
||||
|
||||
NB: This code is under the gmscompat package, but it does not depend on
|
||||
any code from gmscompat.
|
||||
|
||||
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||
|
||||
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||
use the Build field spoofing code it added for model
|
||||
|
||||
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||
---
|
||||
core/java/android/app/Instrumentation.java | 4 ++
|
||||
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||
2 files changed, 63 insertions(+)
|
||||
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
|
||||
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||
index fd6fa57b9e8d..05d840dca223 100644
|
||||
--- a/core/java/android/app/Instrumentation.java
|
||||
+++ b/core/java/android/app/Instrumentation.java
|
||||
@@ -57,6 +57,8 @@ import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.internal.content.ReferrerIntent;
|
||||
|
||||
+import com.android.internal.gmscompat.AttestationHooks;
|
||||
+
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -1188,6 +1190,7 @@ public class Instrumentation {
|
||||
Application app = getFactory(context.getPackageName())
|
||||
.instantiateApplication(cl, className);
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -1205,6 +1208,7 @@ public class Instrumentation {
|
||||
ClassNotFoundException {
|
||||
Application app = (Application)clazz.newInstance();
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
new file mode 100644
|
||||
index 000000000000..621156eb84b9
|
||||
--- /dev/null
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2021 The Android Open Source Project
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+
|
||||
+package com.android.internal.gmscompat;
|
||||
+
|
||||
+import android.app.Application;
|
||||
+import android.os.Build;
|
||||
+import android.os.SystemProperties;
|
||||
+import android.util.Log;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+
|
||||
+/** @hide */
|
||||
+public final class AttestationHooks {
|
||||
+ private static final String TAG = "GmsCompat/Attestation";
|
||||
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+
|
||||
+ private AttestationHooks() { }
|
||||
+
|
||||
+ private static void setBuildField(String key, String value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void spoofBuildGms() {
|
||||
+ // Alter model name to avoid hardware attestation enforcement
|
||||
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ }
|
||||
+
|
||||
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||
Subject: [PATCH 2/8] 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
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||
.../security/keystore2/AndroidKeyStoreSpi.java | 3 +++
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 621156eb84b9..fe12dfe02a9f 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
+import java.util.Arrays;
|
||||
|
||||
/** @hide */
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
|
||||
+ private static volatile boolean sIsGms = false;
|
||||
+
|
||||
private AttestationHooks() { }
|
||||
|
||||
private static void setBuildField(String key, String value) {
|
||||
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ 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) {
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||
>=33
|
||||
|
||||
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||
Setting it to 32 allows for software attestation and passing CTS.
|
||||
|
||||
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index fe12dfe02a9f..f512adc3985b 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||
}
|
||||
}
|
||||
|
||||
+ private static void setVersionField(String key, Integer value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name to avoid hardware attestation enforcement
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
+ }
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||
|
||||
The unstable process is where SafetyNet attestation actually runs, so
|
||||
we only need to spoof the model in that process. Leaving other processes
|
||||
fixes various issues caused by model detection and flag provisioning,
|
||||
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||
weather and settings on Android 12, and more.
|
||||
|
||||
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index f512adc3985b..c1021dd2eb22 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
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;
|
||||
|
||||
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||
aswell
|
||||
|
||||
Play Store is used for the new Play Integrity API, extend the hack
|
||||
to it aswell
|
||||
|
||||
Test: Device Integrity and Basic Integrity passes.
|
||||
|
||||
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index c1021dd2eb22..6a4aab000fe0 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||
|
||||
private static volatile boolean sIsGms = false;
|
||||
+ private static volatile boolean sIsFinsky = false;
|
||||
|
||||
private AttestationHooks() { }
|
||||
|
||||
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
+
|
||||
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
+ sIsFinsky = true;
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||
if (sIsGms && isCallerSafetyNet()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
+
|
||||
+ // Check stack for PlayIntegrity
|
||||
+ if (sIsFinsky) {
|
||||
+ throw new UnsupportedOperationException();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||
|
||||
Google seems to have patched the KM block to Play Store in record time,
|
||||
but is still not enforced for anything under android N.
|
||||
|
||||
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||
anymore, however the KM block is still needed.
|
||||
|
||||
Test: Run Play Intregrity Attestation
|
||||
|
||||
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
- // Alter model name to avoid hardware attestation enforcement
|
||||
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||
|
||||
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
sIsFinsky = true;
|
||||
- spoofBuildGms();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||
|
||||
The logic behind CTS and Play Integrity has been updated today it now
|
||||
checks the product and model names against the fingerprint and if
|
||||
they do not match the CTS profile will fail.
|
||||
|
||||
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||
for key attestation blocking for debugging.
|
||||
|
||||
Test: Boot, check for CTS and Play Integrity
|
||||
|
||||
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
- setBuildField("MODEL", Build.MODEL + " ");
|
||||
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
- }
|
||||
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
+ setBuildField("PRODUCT", "marlin");
|
||||
+ setBuildField("DEVICE", "marlin");
|
||||
+ setBuildField("MODEL", "Pixel XL");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||
+ return sIsGms && 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();
|
||||
- }
|
||||
-
|
||||
- // Check stack for PlayIntegrity
|
||||
- if (sIsFinsky) {
|
||||
+ // Check stack for SafetyNet or Play Integrity
|
||||
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Davide Garberi <dade.garberi@gmail.com>
|
||||
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||
|
||||
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index b10cb04cb4f3..04a536d8073d 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
- setBuildField("PRODUCT", "marlin");
|
||||
- setBuildField("DEVICE", "marlin");
|
||||
- setBuildField("MODEL", "Pixel XL");
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
+ setBuildField("DEVICE", "bullhead");
|
||||
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||
+ setBuildField("MODEL", "Nexus 5X");
|
||||
+ setBuildField("PRODUCT", "bullhead");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
85
Patches/LineageOS-19.1/android_system_core/snet-19.patch
Normal file
85
Patches/LineageOS-19.1/android_system_core/snet-19.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||
|
||||
Google's SafetyNet integrity checks will check the values of these
|
||||
properties when performing basic attestation. Setting fake values helps
|
||||
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||
|
||||
Note that these properties need to be set very early, before parsing the
|
||||
kernel command-line, as they are read-only properties that the bootloader
|
||||
sets using androidboot kernel arguments. The bootloader's real values
|
||||
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||
software because the verified boot chain is broken in that case.
|
||||
|
||||
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||
|
||||
fastboot: Revert to Android 11 method of checking lock status
|
||||
|
||||
Now that we're setting system-wide properties for SafetyNet, which
|
||||
includes ro.boot.verifiedbootstate=green, fastbootd always detects the
|
||||
bootloader as being locked. Revert to the Android 11 method of reading
|
||||
directly from the kernel cmdline to work arround the issue.
|
||||
|
||||
- Also don't set these in recovery
|
||||
|
||||
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||
---
|
||||
fastboot/device/utility.cpp | 7 ++++++-
|
||||
init/property_service.cpp | 17 +++++++++++++++++
|
||||
2 files changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fastboot/device/utility.cpp b/fastboot/device/utility.cpp
|
||||
index b8b3119ac..f9267e0eb 100644
|
||||
--- a/fastboot/device/utility.cpp
|
||||
+++ b/fastboot/device/utility.cpp
|
||||
@@ -204,7 +204,12 @@ std::vector<std::string> ListPartitions(FastbootDevice* device) {
|
||||
}
|
||||
|
||||
bool GetDeviceLockStatus() {
|
||||
- return android::base::GetProperty("ro.boot.verifiedbootstate", "") == "green";
|
||||
+ std::string cmdline;
|
||||
+ // Return lock status true if unable to read kernel command line.
|
||||
+ if (!android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ return cmdline.find("androidboot.verifiedbootstate=orange") == std::string::npos;
|
||||
}
|
||||
|
||||
bool UpdateAllPartitionMetadata(FastbootDevice* device, const std::string& super_name,
|
||||
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||
index d429fc762..c73a2fa5d 100644
|
||||
--- a/init/property_service.cpp
|
||||
+++ b/init/property_service.cpp
|
||||
@@ -1251,6 +1251,15 @@ static void ProcessBootconfig() {
|
||||
});
|
||||
}
|
||||
|
||||
+static void SetSafetyNetProps() {
|
||||
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||
+ InitPropertySet("ro.warranty_bit", "0");
|
||||
+}
|
||||
+
|
||||
void PropertyInit() {
|
||||
selinux_callback cb;
|
||||
cb.func_audit = PropertyAuditCallback;
|
||||
@@ -1265,6 +1274,14 @@ void PropertyInit() {
|
||||
LOG(FATAL) << "Failed to load serialized property info file";
|
||||
}
|
||||
|
||||
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||
+ // these properties are read-only and will be set to invalid values with
|
||||
+ // androidboot cmdline arguments.
|
||||
+ if (!IsRecoveryMode()) {
|
||||
+ SetSafetyNetProps();
|
||||
+ }
|
||||
+
|
||||
// If arguments are passed both on the command line and in DT,
|
||||
// properties set in DT always have priority over the command-line ones.
|
||||
ProcessKernelDt();
|
510
Patches/LineageOS-20.0/android_frameworks_base/snet-20.patch
Normal file
510
Patches/LineageOS-20.0/android_frameworks_base/snet-20.patch
Normal file
@ -0,0 +1,510 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||
enforcement
|
||||
|
||||
As of September 2, Google is enforcing SafetyNet's previously
|
||||
opportunistic hardware-backed attestation based on device information.
|
||||
Append a space to the device model name in order to avoid such
|
||||
enforcement.
|
||||
|
||||
Also contains:
|
||||
Spoof build fingerprint for Google Play Services
|
||||
|
||||
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||
matches that of the device's stock OS, which has passed CTS testing.
|
||||
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||
|
||||
We used to set the real system build fingerprint to the stock one, but
|
||||
Android relies on each build having a unique fingerprint in order to
|
||||
clear the correct caches and update persistent state for system changes.
|
||||
On devices that no longer receive updates from the OEM, the build
|
||||
fingerprint never changes and Android doesn't account for updates
|
||||
correctly, which causes issues when updating without wiping data.
|
||||
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||
|
||||
Corresponding vendor commit:
|
||||
"Only use stock build fingerprint for Google Play Services"
|
||||
|
||||
NB: This code is under the gmscompat package, but it does not depend on
|
||||
any code from gmscompat.
|
||||
|
||||
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||
|
||||
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||
use the Build field spoofing code it added for model
|
||||
|
||||
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||
---
|
||||
core/java/android/app/Instrumentation.java | 4 ++
|
||||
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||
2 files changed, 63 insertions(+)
|
||||
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
|
||||
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||
index 556058b567f9..44449588bbab 100644
|
||||
--- a/core/java/android/app/Instrumentation.java
|
||||
+++ b/core/java/android/app/Instrumentation.java
|
||||
@@ -57,6 +57,8 @@ import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.internal.content.ReferrerIntent;
|
||||
|
||||
+import com.android.internal.gmscompat.AttestationHooks;
|
||||
+
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -1242,6 +1244,7 @@ public class Instrumentation {
|
||||
Application app = getFactory(context.getPackageName())
|
||||
.instantiateApplication(cl, className);
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -1259,6 +1262,7 @@ public class Instrumentation {
|
||||
ClassNotFoundException {
|
||||
Application app = (Application)clazz.newInstance();
|
||||
app.attach(context);
|
||||
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
new file mode 100644
|
||||
index 000000000000..621156eb84b9
|
||||
--- /dev/null
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2021 The Android Open Source Project
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+
|
||||
+package com.android.internal.gmscompat;
|
||||
+
|
||||
+import android.app.Application;
|
||||
+import android.os.Build;
|
||||
+import android.os.SystemProperties;
|
||||
+import android.util.Log;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+
|
||||
+/** @hide */
|
||||
+public final class AttestationHooks {
|
||||
+ private static final String TAG = "GmsCompat/Attestation";
|
||||
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+
|
||||
+ private AttestationHooks() { }
|
||||
+
|
||||
+ private static void setBuildField(String key, String value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void spoofBuildGms() {
|
||||
+ // Alter model name to avoid hardware attestation enforcement
|
||||
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ }
|
||||
+
|
||||
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||
Subject: [PATCH 2/8] 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
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||
.../security/keystore2/AndroidKeyStoreSpi.java | 3 +++
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 621156eb84b9..fe12dfe02a9f 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
+import java.util.Arrays;
|
||||
|
||||
/** @hide */
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
|
||||
+ private static volatile boolean sIsGms = false;
|
||||
+
|
||||
private AttestationHooks() { }
|
||||
|
||||
private static void setBuildField(String key, String value) {
|
||||
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ 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) {
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||
>=33
|
||||
|
||||
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||
Setting it to 32 allows for software attestation and passing CTS.
|
||||
|
||||
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index fe12dfe02a9f..f512adc3985b 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||
}
|
||||
}
|
||||
|
||||
+ private static void setVersionField(String key, Integer value) {
|
||||
+ try {
|
||||
+ // Unlock
|
||||
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||
+ field.setAccessible(true);
|
||||
+
|
||||
+ // Edit
|
||||
+ field.set(null, value);
|
||||
+
|
||||
+ // Lock
|
||||
+ field.setAccessible(false);
|
||||
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name to avoid hardware attestation enforcement
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
+ }
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||
|
||||
The unstable process is where SafetyNet attestation actually runs, so
|
||||
we only need to spoof the model in that process. Leaving other processes
|
||||
fixes various issues caused by model detection and flag provisioning,
|
||||
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||
weather and settings on Android 12, and more.
|
||||
|
||||
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index f512adc3985b..c1021dd2eb22 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
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;
|
||||
|
||||
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||
aswell
|
||||
|
||||
Play Store is used for the new Play Integrity API, extend the hack
|
||||
to it aswell
|
||||
|
||||
Test: Device Integrity and Basic Integrity passes.
|
||||
|
||||
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index c1021dd2eb22..6a4aab000fe0 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||
public final class AttestationHooks {
|
||||
private static final String TAG = "GmsCompat/Attestation";
|
||||
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||
|
||||
private static volatile boolean sIsGms = false;
|
||||
+ private static volatile boolean sIsFinsky = false;
|
||||
|
||||
private AttestationHooks() { }
|
||||
|
||||
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||
sIsGms = true;
|
||||
spoofBuildGms();
|
||||
}
|
||||
+
|
||||
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
+ sIsFinsky = true;
|
||||
+ spoofBuildGms();
|
||||
+ }
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||
if (sIsGms && isCallerSafetyNet()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
+
|
||||
+ // Check stack for PlayIntegrity
|
||||
+ if (sIsFinsky) {
|
||||
+ throw new UnsupportedOperationException();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||
|
||||
Google seems to have patched the KM block to Play Store in record time,
|
||||
but is still not enforced for anything under android N.
|
||||
|
||||
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||
anymore, however the KM block is still needed.
|
||||
|
||||
Test: Run Play Intregrity Attestation
|
||||
|
||||
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||
---
|
||||
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
- // Alter model name to avoid hardware attestation enforcement
|
||||
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
setBuildField("MODEL", Build.MODEL + " ");
|
||||
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||
|
||||
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||
sIsFinsky = true;
|
||||
- spoofBuildGms();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dyneteve <dyneteve@hentaios.com>
|
||||
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||
|
||||
The logic behind CTS and Play Integrity has been updated today it now
|
||||
checks the product and model names against the fingerprint and if
|
||||
they do not match the CTS profile will fail.
|
||||
|
||||
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||
for key attestation blocking for debugging.
|
||||
|
||||
Test: Boot, check for CTS and Play Integrity
|
||||
|
||||
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||
---
|
||||
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||
- setBuildField("MODEL", Build.MODEL + " ");
|
||||
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||
- }
|
||||
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
+ setBuildField("PRODUCT", "marlin");
|
||||
+ setBuildField("DEVICE", "marlin");
|
||||
+ setBuildField("MODEL", "Pixel XL");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
||||
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||
}
|
||||
|
||||
private static boolean isCallerSafetyNet() {
|
||||
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||
+ return sIsGms && 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();
|
||||
- }
|
||||
-
|
||||
- // Check stack for PlayIntegrity
|
||||
- if (sIsFinsky) {
|
||||
+ // Check stack for SafetyNet or Play Integrity
|
||||
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Davide Garberi <dade.garberi@gmail.com>
|
||||
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||
|
||||
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||
---
|
||||
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
index b10cb04cb4f3..04a536d8073d 100644
|
||||
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||
|
||||
private static void spoofBuildGms() {
|
||||
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||
- setBuildField("PRODUCT", "marlin");
|
||||
- setBuildField("DEVICE", "marlin");
|
||||
- setBuildField("MODEL", "Pixel XL");
|
||||
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||
+ setBuildField("DEVICE", "bullhead");
|
||||
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||
+ setBuildField("MODEL", "Nexus 5X");
|
||||
+ setBuildField("PRODUCT", "bullhead");
|
||||
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||
}
|
||||
|
||||
public static void initApplicationBeforeOnCreate(Application app) {
|
85
Patches/LineageOS-20.0/android_system_core/snet-20.patch
Normal file
85
Patches/LineageOS-20.0/android_system_core/snet-20.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Danny Lin <danny@kdrag0n.dev>
|
||||
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||
|
||||
Google's SafetyNet integrity checks will check the values of these
|
||||
properties when performing basic attestation. Setting fake values helps
|
||||
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||
|
||||
Note that these properties need to be set very early, before parsing the
|
||||
kernel command-line, as they are read-only properties that the bootloader
|
||||
sets using androidboot kernel arguments. The bootloader's real values
|
||||
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||
software because the verified boot chain is broken in that case.
|
||||
|
||||
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||
|
||||
fastboot: Revert to Android 11 method of checking lock status
|
||||
|
||||
Now that we're setting system-wide properties for SafetyNet, which
|
||||
includes ro.boot.verifiedbootstate=green, fastbootd always detects the
|
||||
bootloader as being locked. Revert to the Android 11 method of reading
|
||||
directly from the kernel cmdline to work arround the issue.
|
||||
|
||||
- Also don't set these in recovery
|
||||
|
||||
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||
---
|
||||
fastboot/device/utility.cpp | 7 ++++++-
|
||||
init/property_service.cpp | 17 +++++++++++++++++
|
||||
2 files changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fastboot/device/utility.cpp b/fastboot/device/utility.cpp
|
||||
index 2d9b71213..a14eea376 100644
|
||||
--- a/fastboot/device/utility.cpp
|
||||
+++ b/fastboot/device/utility.cpp
|
||||
@@ -196,7 +196,12 @@ std::vector<std::string> ListPartitions(FastbootDevice* device) {
|
||||
}
|
||||
|
||||
bool GetDeviceLockStatus() {
|
||||
- return android::base::GetProperty("ro.boot.verifiedbootstate", "") == "green";
|
||||
+ std::string cmdline;
|
||||
+ // Return lock status true if unable to read kernel command line.
|
||||
+ if (!android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ return cmdline.find("androidboot.verifiedbootstate=orange") == std::string::npos;
|
||||
}
|
||||
|
||||
bool UpdateAllPartitionMetadata(FastbootDevice* device, const std::string& super_name,
|
||||
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||
index 7fd64b389..06709cb7c 100644
|
||||
--- a/init/property_service.cpp
|
||||
+++ b/init/property_service.cpp
|
||||
@@ -1286,6 +1286,15 @@ static void ProcessBootconfig() {
|
||||
});
|
||||
}
|
||||
|
||||
+static void SetSafetyNetProps() {
|
||||
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||
+ InitPropertySet("ro.warranty_bit", "0");
|
||||
+}
|
||||
+
|
||||
void PropertyInit() {
|
||||
selinux_callback cb;
|
||||
cb.func_audit = PropertyAuditCallback;
|
||||
@@ -1300,6 +1309,14 @@ void PropertyInit() {
|
||||
LOG(FATAL) << "Failed to load serialized property info file";
|
||||
}
|
||||
|
||||
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||
+ // these properties are read-only and will be set to invalid values with
|
||||
+ // androidboot cmdline arguments.
|
||||
+ if (!IsRecoveryMode()) {
|
||||
+ SetSafetyNetProps();
|
||||
+ }
|
||||
+
|
||||
// If arguments are passed both on the command line and in DT,
|
||||
// properties set in DT always have priority over the command-line ones.
|
||||
ProcessKernelDt();
|
@ -929,8 +929,10 @@ export -f changeDefaultDNS;
|
||||
|
||||
editKernelLocalversion() {
|
||||
local defconfigPath=$(getDefconfig)
|
||||
sed -i 's/CONFIG_LOCALVERSION=".*"/CONFIG_LOCALVERSION="'"$1"'"/' $defconfigPath &>/dev/null || true;
|
||||
sed -zi '/CONFIG_LOCALVERSION="'"$1"'"/!s/$/\nCONFIG_LOCALVERSION="'"$1"'"/' $defconfigPath &>/dev/null;
|
||||
local replacement=$1;
|
||||
if [ "$DOS_SNET" = true ]; then local replacement="-oink"; fi;
|
||||
sed -i 's/CONFIG_LOCALVERSION=".*"/CONFIG_LOCALVERSION="'"$replacement"'"/' $defconfigPath &>/dev/null || true;
|
||||
sed -zi '/CONFIG_LOCALVERSION="'"$replacement"'"/!s/$/\nCONFIG_LOCALVERSION="'"$replacement"'"/' $defconfigPath &>/dev/null;
|
||||
}
|
||||
export -f editKernelLocalversion;
|
||||
|
||||
|
@ -196,6 +196,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Sensors_Permission.patch";
|
||||
if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/0014-constify_JNINativeMethod.patch"; fi; #Constify JNINativeMethod tables (GrapheneOS)
|
||||
#if [ "$DOS_MICROG_SUPPORT" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/0021-Unprivileged_microG_Handling.patch"; fi; #Unprivileged microG handling (heavily based off of a CalyxOS patch)
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||
if [ "$DOS_SNET" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/snet-16.patch"; fi;
|
||||
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
||||
sed -i 's/DEFAULT_MAX_FILES_LOWRAM = 300;/DEFAULT_MAX_FILES_LOWRAM = 0;/' services/core/java/com/android/server/DropBoxManagerService.java;
|
||||
sed -i 's/(notif.needNotify)/(true)/' location/java/com/android/internal/location/GpsNetInitiatedHandler.java; #Notify the user if their location is requested via SUPL
|
||||
@ -381,6 +382,7 @@ applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts
|
||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
||||
#applyPatch "$DOS_PATCHES/android_system_core/0004-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-16.patch"; fi;
|
||||
fi;
|
||||
|
||||
if enterAndClear "system/extras"; then
|
||||
|
@ -219,6 +219,7 @@ if [ "$DOS_MICROG_SUPPORT" = true ]; then applyPatch "$DOS_PATCHES/android_frame
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0006-Do-not-throw-in-setAppOnInterfaceLocked.patch"; #Fix random reboots on broken kernels when an app has data restricted XXX: ugly (DivestOS)
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||
if [ "$DOS_SNET" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/snet-17.patch"; fi;
|
||||
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
||||
sed -i 's/DEFAULT_MAX_FILES_LOWRAM = 300;/DEFAULT_MAX_FILES_LOWRAM = 0;/' services/core/java/com/android/server/DropBoxManagerService.java;
|
||||
sed -i 's/(notif.needNotify)/(true)/' location/java/com/android/internal/location/GpsNetInitiatedHandler.java; #Notify the user if their location is requested via SUPL
|
||||
@ -430,6 +431,7 @@ applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts
|
||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
||||
applyPatch "$DOS_PATCHES/android_system_core/0004-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-17.patch"; fi;
|
||||
fi;
|
||||
|
||||
if enterAndClear "system/extras"; then
|
||||
|
@ -174,6 +174,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0025-tile_restrictions.patch";
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0006-Do-not-throw-in-setAppOnInterfaceLocked.patch"; #Fix random reboots on broken kernels when an app has data restricted XXX: ugly (DivestOS)
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||
if [ "$DOS_SNET" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/snet-18.patch"; fi;
|
||||
hardenLocationConf services/core/java/com/android/server/location/gps_debug.conf; #Harden the default GPS config
|
||||
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
||||
sed -i 's/DEFAULT_USE_FREEZER = false;/DEFAULT_USE_FREEZER = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app freezer by default (GrapheneOS)
|
||||
@ -401,6 +402,7 @@ applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts
|
||||
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0004-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
||||
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-18.patch"; fi;
|
||||
fi;
|
||||
|
||||
if enterAndClear "system/extras"; then
|
||||
|
@ -182,6 +182,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0032-tile_restrictions.patch";
|
||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0033-minimal_screenshot_exif.patch"; #Put bare minimum metadata in screenshots (CalyxOS)
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||
if [ "$DOS_SNET" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/snet-19.patch"; fi;
|
||||
hardenLocationConf services/core/java/com/android/server/location/gnss/gps_debug.conf; #Harden the default GPS config
|
||||
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
||||
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
||||
@ -403,6 +404,7 @@ git revert --no-edit 07adb89d0f8c966c88869d1abffc57da0e707568; #insanity
|
||||
applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS)
|
||||
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-19.patch"; fi;
|
||||
fi;
|
||||
|
||||
if enterAndClear "system/extras"; then
|
||||
|
@ -197,6 +197,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0039-package_hooks.patch"; #Add
|
||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0040-euicc-restrictions.patch"; #Integrate Google's EuiccSupportPixel package (GrapheneOS)
|
||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0041-tile_restrictions.patch"; #SystemUI: Require unlocking to use sensitive QS tiles (GrapheneOS)
|
||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0042-minimal_screenshot_exif.patch"; #Put bare minimum metadata in screenshots (CalyxOS)
|
||||
if [ "$DOS_SNET" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/snet-20.patch"; fi;
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||
hardenLocationConf services/core/java/com/android/server/location/gnss/gps_debug.conf; #Harden the default GPS config
|
||||
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
||||
@ -418,6 +419,7 @@ git revert --no-edit 942dd2ac9eed11d0ff31fb734de46c2da24b4b9b; #unknown impact
|
||||
applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS)
|
||||
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-20.patch"; fi;
|
||||
fi;
|
||||
|
||||
if enterAndClear "system/extras"; then
|
||||
|
@ -67,6 +67,8 @@ export DOS_GRAPHENE_EXEC=true; #Enables use of GrapheneOS' exec spawning feature
|
||||
export DOS_HOSTS_BLOCKING=true; #Set false to prevent inclusion of a HOSTS file
|
||||
export DOS_HOSTS_BLOCKING_LIST="https://divested.dev/hosts-wildcards"; #Must be in the format "127.0.0.1 bad.domain.tld"
|
||||
export DOS_MICROG_SUPPORT=true; #Opt-in unprivileged microG support on 17.1+18.1+19.1+20.0
|
||||
export DOS_SNET=false; #Selectively spoof select build properties
|
||||
export DOS_SNET_EXTRA=false; #Globally spoof select bootloader properties
|
||||
export DOS_SENSORS_PERM=false; #Set true to provide a per-app sensors permission for 14.1/15.1 #XXX: can break things like camera
|
||||
export DOS_STRONG_ENCRYPTION_ENABLED=false; #Set true to enable AES 256-bit FDE encryption on 14.1+15.1 #XXX: THIS WILL **DESTROY** EXISTING INSTALLS!
|
||||
export DOS_USE_KSM=false; #Set true to use KSM for increased memory efficiency at the cost of easier side-channel attacks and increased CPU usage #XXX: testing only
|
||||
@ -145,6 +147,11 @@ if [ ! -d "$DOS_BUILD_BASE" ]; then
|
||||
return 1;
|
||||
fi;
|
||||
|
||||
if [ "$DOS_MICROG_SUPPORT" = false ]; then
|
||||
export DOS_SNET=false;
|
||||
export DOS_SNET_EXTRA=false;
|
||||
fi;
|
||||
|
||||
export DOS_TMP_DIR="/tmp/dos_tmp";
|
||||
mkdir -p "$DOS_TMP_DIR";
|
||||
export DOS_HOSTS_FILE="$DOS_TMP_DIR/hosts";
|
||||
|
Loading…
Reference in New Issue
Block a user