Skip to content

Commit

Permalink
keystore: Block key attestation for Google Play Services
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kdrag0n committed Jan 14, 2021
1 parent 2d6ff19 commit f106ca4
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
10 changes: 8 additions & 2 deletions keystore/key_store_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include "keystore_utils.h"
#include <keystore/keystore_hidl_support.h>

#include <hardware/keymaster_defs.h>

namespace keystore {

using namespace android;
Expand Down Expand Up @@ -103,8 +105,12 @@ 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");
return ErrorCode::ATTESTATION_APPLICATION_ID_MISSING;
if (asn1_attestation_id_result.status() == KM_ERROR_UNIMPLEMENTED) {
return KeyStoreServiceReturnCode(ErrorCode(KM_ERROR_UNIMPLEMENTED));
} else {
ALOGE("failed to gather attestation_id");
return ErrorCode::ATTESTATION_APPLICATION_ID_MISSING;
}
}
std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;

Expand Down
6 changes: 6 additions & 0 deletions keystore/keystore_attestation_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include <keystore/KeyAttestationPackageInfo.h>
#include <keystore/Signature.h>

#include <hardware/keymaster_defs.h>

#include <openssl/asn1t.h>
#include <openssl/sha.h>

Expand Down Expand Up @@ -165,6 +167,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) {
Expand Down

0 comments on commit f106ca4

Please sign in to comment.