From 279c1a918bec24a53a476b87bf0575771a3617e3 Mon Sep 17 00:00:00 2001 From: Danny Lin Date: Wed, 13 Jan 2021 19:21:26 -0800 Subject: [PATCH] Add Android 11 patch files --- Makefile | 2 +- ...ey-attestation-for-Google-Play-Servi.patch | 52 +++++++++++ ...ey-attestation-for-Google-Play-Servi.patch | 90 +++++++++++++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 patches/0001-KeyStore-Block-key-attestation-for-Google-Play-Servi.patch create mode 100644 patches/0001-keystore-Block-key-attestation-for-Google-Play-Servi.patch diff --git a/Makefile b/Makefile index 48b3d0b..95e2e57 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ all: $(ZIP) zip: $(ZIP) %.zip: clean - zip -r9 $(ZIP) . -x $(MODNAME)-*.zip LICENSE .gitignore .gitattributes Makefile /.git* *.DS_Store* *placeholder + zip -r9 $(ZIP) . -x $(MODNAME)-*.zip LICENSE .gitignore .gitattributes Makefile /.git* *.DS_Store* *placeholder patches/ patches/* install: $(ZIP) adb push $(ZIP) /sdcard/ diff --git a/patches/0001-KeyStore-Block-key-attestation-for-Google-Play-Servi.patch b/patches/0001-KeyStore-Block-key-attestation-for-Google-Play-Servi.patch new file mode 100644 index 0000000..787ea5a --- /dev/null +++ b/patches/0001-KeyStore-Block-key-attestation-for-Google-Play-Servi.patch @@ -0,0 +1,52 @@ +From 7f7a9b19c8293c09dfee12bec75ff17225c6710e Mon Sep 17 00:00:00 2001 +From: Danny Lin +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 +--- + 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 88b614dc7eef..0f766ef738bf 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.29.2 + diff --git a/patches/0001-keystore-Block-key-attestation-for-Google-Play-Servi.patch b/patches/0001-keystore-Block-key-attestation-for-Google-Play-Servi.patch new file mode 100644 index 0000000..6a7bd77 --- /dev/null +++ b/patches/0001-keystore-Block-key-attestation-for-Google-Play-Servi.patch @@ -0,0 +1,90 @@ +From 15633a3d29bf727b83083f2c49d906c16527d389 Mon Sep 17 00:00:00 2001 +From: Danny Lin +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 +--- + 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 + + #include ++#include + + 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(); ++ 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(); ++ } + } + std::vector& 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 + #include + ++#include ++ + #include /* for AID_SYSTEM */ + + #include +@@ -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 attestation_package_info; + auto rc = build_attestation_package_info(*pinfo, &attestation_package_info); + if (rc != NO_ERROR) { +-- +2.29.2 +