Skip to content

Commit

Permalink
fajita: Add patches that are applied additionally
Browse files Browse the repository at this point in the history
Signed-off-by: bananafunction <terathree2@web.de>
  • Loading branch information
bananafunction committed Sep 7, 2021
1 parent 2139094 commit e1925d1
Show file tree
Hide file tree
Showing 13 changed files with 755 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
From 79f88023815c81f7f384561f71ef0e628d73d52f Mon Sep 17 00:00:00 2001
From: Danny Lin <danny@kdrag0n.dev>
Date: Tue, 12 Jan 2021 22:25:13 -0800
Subject: [PATCH] KeyStore: Block key attestation for Google Play Services

In order to enforce SafetyNet security, Google Play Services is now
using hardware attestation for ctsProfile validation in all cases, even
when basic attestation is selected. The SafetyNet API response from GMS
will report that basic attestation was used, but under the hood,
hardware attestation is always used regardless of the reported state.
This results in SafetyNet failing to pass due to TrustZone reporting an
unlocked bootloader (and a partially invalidated root of trust) in the
key attestation result.

We can still take advantage of the fact that this usage of hardware
attestation is opportunistic - that is, it falls back to basic
attestation if key attestation fails to run - and prevent GMS from using
key attestation at the framework level. This causes it to gracefully
fall back to basic attestation and pass SafetyNet with an unlocked
bootloader.

Key attestation is still available for other apps, as there are valid
uses for it that do not involve SafetyNet.

The "not implemented" error code from keymaster is used to simulate the
most realistic failure condition to evade detection, i.e. an old device
that lacks support for key attestation.

Change-Id: I7282ab22b933434bb11037743d46b8a20dad063a
Signed-off-by: Anushek Prasal <anushekprasal@gmail.com>
---
keystore/java/android/security/KeyStore.java | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 88b614dc7ee..0f766ef738b 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -1124,6 +1124,11 @@ public class KeyStore {

public int attestKey(
String alias, KeymasterArguments params, KeymasterCertificateChain outChain) {
+ // Prevent Google Play Services from using key attestation for SafetyNet
+ if (mContext.getPackageName().equals("com.google.android.gms")) {
+ return KeymasterDefs.KM_ERROR_UNIMPLEMENTED;
+ }
+
CertificateChainPromise promise = new CertificateChainPromise();
try {
mBinder.asBinder().linkToDeath(promise, 0);
--
2.25.1

35 changes: 35 additions & 0 deletions patches/0001-fajita-use-fingerprint-of-Pixel-device.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
From 06a86d3fa3cf77394be22ca0dc83032b016d744a Mon Sep 17 00:00:00 2001
From: bananafunction <terathree2@web.de>
Date: Tue, 7 Sep 2021 09:08:44 +0200
Subject: [PATCH] fajita: use fingerprint of Pixel device

This change allows Google Play Store certification, as the current
chosen fingerprint needs to fit to current Android Security Patch
Level (SPL).

As a consequence, when updating SPL, an update of this fingerprint
is mandatory to stay certified.

Signed-off-by: bananafunction <terathree2@web.de>
---
lineage_fajita.mk | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lineage_fajita.mk b/lineage_fajita.mk
index 59974d9..2cec946 100644
--- a/lineage_fajita.mk
+++ b/lineage_fajita.mk
@@ -35,6 +35,8 @@ PRODUCT_GMS_CLIENTID_BASE := android-oneplus
PRODUCT_BUILD_PROP_OVERRIDES += \
PRODUCT_DEVICE=OnePlus6T \
PRODUCT_NAME=OnePlus6T \
- PRIVATE_BUILD_DESC="OnePlus6T-user 9 PKQ1.180716.001 1812260627 release-keys"
+ PRIVATE_BUILD_DESC="redfin-user 11 RQ3A.210805.001.A1 7474174 release-keys" \
+ BUILD_NUMBER=7474174

-BUILD_FINGERPRINT := OnePlus/OnePlus6T/OnePlus6T:9/PKQ1.180716.001/1812260627:user/release-keys
+# Pixel 5 August fingerprint
+BUILD_FINGERPRINT := google/redfin/redfin:11/RQ3A.210805.001.A1/7474174:user/release-keys
--
2.25.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
From 22e25eba9ef58a3f4e6511a7984def78e6914dd3 Mon Sep 17 00:00:00 2001
From: Alex Naidis <alex.naidis@linux.com>
Date: Sun, 9 Apr 2017 01:29:27 +0200
Subject: [PATCH 1/7] init: Weaken property override security for the init
extension

Sometimes we need to override ro.* properties by using our vendor init
extension.

Previously there was a security check which was blocking that.
To resolve the issue, we need to weaken the security check during the
execution of our vendor init extension.

This is safe because the vendor init extension gets executed as part of init
construction and it is considered a trusted system component.

Change-Id: Ia7d60686968695f1fb43be4ed58770ce10da88c5

Former-commit-id: 91d12168b9500a44211a7d5a092e0ebcfed48d4d
Signed-off-by: Anushek Prasal <anushekprasal@gmail.com>
---
init/property_service.cpp | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/init/property_service.cpp b/init/property_service.cpp
index 42dd5afcb..058758ae0 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -108,6 +108,8 @@ struct PropertyAuditData {
const char* name;
};

+static bool weaken_prop_override_security = false;
+
static int PropertyAuditCallback(void* data, security_class_t /*cls*/, char* buf, size_t len) {
auto* d = reinterpret_cast<PropertyAuditData*>(data);

@@ -178,8 +180,8 @@ static uint32_t PropertySet(const std::string& name, const std::string& value, s

prop_info* pi = (prop_info*) __system_property_find(name.c_str());
if (pi != nullptr) {
- // ro.* properties are actually "write-once".
- if (StartsWith(name, "ro.")) {
+ // ro.* properties are actually "write-once", unless the system decides to
+ if (StartsWith(name, "ro.") && !weaken_prop_override_security) {
*error = "Read-only property was already set";
return PROP_ERROR_READ_ONLY_PROPERTY;
}
@@ -913,12 +915,18 @@ void PropertyLoadBootDefaults() {
}
}

+ // Weaken property override security during execution of the vendor init extension
+ weaken_prop_override_security = true;
+
// Update with vendor-specific property runtime overrides
vendor_load_properties();

property_initialize_ro_product_props();
property_derive_build_fingerprint();

+ // Restore the normal property override security after init extension is executed
+ weaken_prop_override_security = false;
+
if (android::base::GetBoolProperty("ro.persistent_properties.ready", false)) {
update_sys_usb_config();
}

--
2.25.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
From 079146f8863ec96a8341fa83b5bca4301d2a6ad7 Mon Sep 17 00:00:00 2001
From: Danny Lin <danny@kdrag0n.dev>
Date: Wed, 13 Jan 2021 02:05:05 -0800
Subject: [PATCH] keystore: Block key attestation for Google Play Services

In order to enforce SafetyNet security, Google Play Services is now
using hardware attestation for ctsProfile validation in all cases, even
when basic attestation is selected. The SafetyNet API response from GMS
will report that basic attestation was used, but under the hood,
hardware attestation is always used regardless of the reported state.
This results in SafetyNet failing to pass due to TrustZone reporting an
unlocked bootloader (and a partially invalidated root of trust) in the
key attestation result.

We can still take advantage of the fact that this usage of hardware
attestation is opportunistic - that is, it falls back to basic
attestation if key attestation fails to run - and prevent GMS from using
key attestation at the framework level. This causes it to gracefully
fall back to basic attestation and pass SafetyNet with an unlocked
bootloader.

Key attestation is still available for other apps, as there are valid
uses for it that do not involve SafetyNet.

The "not implemented" error code from keymaster is used to simulate the
most realistic failure condition to evade detection, i.e. an old device
that lacks support for key attestation.

Change-Id: Iba5fe0791622839e1bad4730593a319ea03661f2
Signed-off-by: Anushek Prasal <anushekprasal@gmail.com>
---
keystore/key_store_service.cpp | 11 ++++++++---
keystore/keystore_attestation_id.cpp | 6 ++++++
2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 1b38643..b1f1304 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -49,6 +49,7 @@
#include <keystore/keystore_return_types.h>

#include <hardware/hw_auth_token.h>
+#include <hardware/keymaster_defs.h>

namespace keystore {

@@ -120,9 +121,13 @@ KeyStoreServiceReturnCode updateParamsForAttestation(uid_t callingUid, Authoriza

auto asn1_attestation_id_result = security::gather_attestation_application_id(callingUid);
if (!asn1_attestation_id_result.isOk()) {
- ALOGE("failed to gather attestation_id");
- // Couldn't get attestation ID; just use an empty one rather than failing.
- asn1_attestation_id_result = std::vector<uint8_t>();
+ if (asn1_attestation_id_result.status() == KM_ERROR_UNIMPLEMENTED) {
+ return KeyStoreServiceReturnCode(KM_ERROR_UNIMPLEMENTED);
+ } else {
+ ALOGE("failed to gather attestation_id");
+ // Couldn't get attestation ID; just use an empty one rather than failing.
+ asn1_attestation_id_result = std::vector<uint8_t>();
+ }
}
std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;

diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
index 3d9e87e..448a909 100644
--- a/keystore/keystore_attestation_id.cpp
+++ b/keystore/keystore_attestation_id.cpp
@@ -35,6 +35,8 @@
#include <keystore/KeyAttestationPackageInfo.h>
#include <keystore/Signature.h>

+#include <hardware/keymaster_defs.h>
+
#include <private/android_filesystem_config.h> /* for AID_SYSTEM */

#include <openssl/asn1t.h>
@@ -210,6 +212,10 @@ build_attestation_application_id(const KeyAttestationApplicationId& key_attestat
return BAD_VALUE;
}
std::string package_name(String8(*pinfo->package_name()).string());
+ // Prevent Google Play Services from using key attestation for SafetyNet
+ if (package_name == "com.google.android.gms") {
+ return KM_ERROR_UNIMPLEMENTED;
+ }
std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO> attestation_package_info;
auto rc = build_attestation_package_info(*pinfo, &attestation_package_info);
if (rc != NO_ERROR) {
--
2.25.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
From e42af38553fc474c4c3b35122ccf85f2aadc45f1 Mon Sep 17 00:00:00 2001
From: Dyneteve <dyneteve@hentaios.com>
Date: Sun, 31 Jan 2021 02:19:54 +0900
Subject: [PATCH] KeyStore: Report rate limited instead of not implemented

Signed-off-by: Anushek Prasal <anushekprasal@gmail.com>
---
keystore/java/android/security/KeyStore.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 0f766ef738b..b89adedb5e8 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -1126,7 +1126,7 @@ public class KeyStore {
String alias, KeymasterArguments params, KeymasterCertificateChain outChain) {
// Prevent Google Play Services from using key attestation for SafetyNet
if (mContext.getPackageName().equals("com.google.android.gms")) {
- return KeymasterDefs.KM_ERROR_UNIMPLEMENTED;
+ return KeymasterDefs.KM_ERROR_KEY_RATE_LIMIT_EXCEEDED;
}

CertificateChainPromise promise = new CertificateChainPromise();
--
2.25.1

82 changes: 82 additions & 0 deletions patches/0002-init-workaround-SafetyNet-check_SysCore.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
From 363cf0d238df8bf8d3954c801c1b41f495a25747 Mon Sep 17 00:00:00 2001
From: Park Ju Hyung <qkrwngud825@gmail.com>
Date: Mon, 6 Nov 2017 20:30:39 +0900
Subject: [PATCH 2/7] init: workaround SafetyNet check

Doing this in the userspace allows more properties to be spoofed
and eliminate the needs for a hack in the kernel.

Former-commit-id: e036a461c7dd4d97e1df77979c85f3c198e1e784
Signed-off-by: Anushek Prasal <anushekprasal@gmail.com>
---
init/property_service.cpp | 47 +++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)

diff --git a/init/property_service.cpp b/init/property_service.cpp
index 7631bacd0..7ab7a8e76 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -773,6 +773,50 @@ static void load_override_properties() {
}
}

+static const char *snet_prop_key[] = {
+ "ro.boot.vbmeta.device_state",
+ "ro.boot.verifiedbootstate",
+ "ro.boot.flash.locked",
+ "ro.boot.selinux",
+ "ro.boot.veritymode",
+ "ro.boot.warranty_bit",
+ "ro.warranty_bit",
+ "ro.debuggable",
+ "ro.secure",
+ "ro.build.type",
+ "ro.build.keys",
+ "ro.build.tags",
+ "ro.system.build.tags",
+ NULL
+};
+
+static const char *snet_prop_value[] = {
+ "locked", // ro.boot.vbmeta.device_state
+ "green", // ro.boot.verifiedbootstate
+ "1", // ro.boot.flash.locked
+ "enforcing", // ro.boot.selinux
+ "enforcing", // ro.boot.veritymode
+ "0", // ro.boot.warranty_bit
+ "0", // ro.warranty_bit
+ "0", // ro.debuggable
+ "1", // ro.secure
+ "user", // ro.build.type
+ "release-keys", // ro.build.keys
+ "release-keys", // ro.build.tags
+ "release-keys", // ro.system.build.tags
+ NULL
+};
+
+static void workaround_snet_properties() {
+ std::string error;
+ LOG(INFO) << "snet: Hiding sensitive props";
+
+ // Hide all sensitive props
+ for (int i = 0; snet_prop_key[i]; ++i) {
+ PropertySet(snet_prop_key[i], snet_prop_value[i], &error);
+ }
+}
+
// If the ro.product.[brand|device|manufacturer|model|name] properties have not been explicitly
// set, derive them from ro.product.${partition}.* properties
static void property_initialize_ro_product_props() {
@@ -924,6 +968,9 @@ void PropertyLoadBootDefaults() {
property_initialize_ro_product_props();
property_derive_build_fingerprint();

+ // Workaround SafetyNet
+ workaround_snet_properties();
+
// Restore the normal property override security after init extension is executed
weaken_prop_override_security = false;

--
2.25.1

Loading

0 comments on commit e1925d1

Please sign in to comment.