mirror of
https://github.com/kdrag0n/safetynet-fix.git
synced 2024-09-03 13:29:02 +00:00
91 lines
3.8 KiB
Diff
91 lines
3.8 KiB
Diff
|
From 15633a3d29bf727b83083f2c49d906c16527d389 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
|
||
|
---
|
||
|
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.29.2
|
||
|
|