Add device id attestation
This adds device id attestation to KeyStoreService. The service
validates that the user holds the required permissions before
allowing attestation to proceed.
Bug: 34597337
Test: CTS CtsKeystoreTestCases and GTS DeviceIdAttestationHostTest
Change-Id: I6ff6146fad4656b8e1367650de922124b3d7f7b2
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index d4032c1..417a164 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -24,7 +24,10 @@
#include <algorithm>
#include <sstream>
+#include <binder/IInterface.h>
#include <binder/IPCThreadState.h>
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
#include <private/android_filesystem_config.h>
@@ -1229,6 +1232,23 @@
constexpr size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
+bool isDeviceIdAttestationRequested(const hidl_vec<KeyParameter>& params) {
+ for (size_t i = 0; i < params.size(); ++i) {
+ switch (params[i].tag) {
+ case Tag::ATTESTATION_ID_BRAND:
+ case Tag::ATTESTATION_ID_DEVICE:
+ case Tag::ATTESTATION_ID_PRODUCT:
+ case Tag::ATTESTATION_ID_SERIAL:
+ case Tag::ATTESTATION_ID_IMEI:
+ case Tag::ATTESTATION_ID_MEID:
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
KeyStoreServiceReturnCode KeyStoreService::attestKey(const String16& name,
const hidl_vec<KeyParameter>& params,
hidl_vec<hidl_vec<uint8_t>>* outChain) {
@@ -1242,6 +1262,19 @@
uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ bool attestingDeviceIds = isDeviceIdAttestationRequested(params);
+ if (attestingDeviceIds) {
+ sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+ if (binder == 0) {
+ return ErrorCode::CANNOT_ATTEST_IDS;
+ }
+ if (!interface_cast<IPermissionController>(binder)->checkPermission(
+ String16("android.permission.READ_PRIVILEGED_PHONE_STATE"),
+ IPCThreadState::self()->getCallingPid(), callingUid)) {
+ return ErrorCode::CANNOT_ATTEST_IDS;
+ }
+ }
+
Blob keyBlob;
String8 name8(name);
KeyStoreServiceReturnCode responseCode =
@@ -1279,12 +1312,23 @@
auto hidlKey = blob2hidlVec(keyBlob);
auto& dev = mKeyStore->getDevice(keyBlob);
- KeyStoreServiceReturnCode rc =
+ KeyStoreServiceReturnCode attestationRc =
KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), hidlCb));
- if (!rc.isOk()) {
- return rc;
+
+ KeyStoreServiceReturnCode deletionRc;
+ if (attestingDeviceIds) {
+ // When performing device id attestation, treat the key as ephemeral and delete it straight
+ // away.
+ deletionRc = KS_HANDLE_HIDL_ERROR(dev->deleteKey(hidlKey));
}
- return error;
+
+ if (!attestationRc.isOk()) {
+ return attestationRc;
+ }
+ if (!error.isOk()) {
+ return error;
+ }
+ return deletionRc;
}
KeyStoreServiceReturnCode KeyStoreService::onDeviceOffBody() {
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
index 117f048..8333860 100644
--- a/keystore/keymaster_enforcement.cpp
+++ b/keystore/keymaster_enforcement.cpp
@@ -289,6 +289,12 @@
case Tag::APPLICATION_DATA:
case Tag::ATTESTATION_CHALLENGE:
case Tag::ATTESTATION_APPLICATION_ID:
+ case Tag::ATTESTATION_ID_BRAND:
+ case Tag::ATTESTATION_ID_DEVICE:
+ case Tag::ATTESTATION_ID_PRODUCT:
+ case Tag::ATTESTATION_ID_SERIAL:
+ case Tag::ATTESTATION_ID_IMEI:
+ case Tag::ATTESTATION_ID_MEID:
return ErrorCode::INVALID_KEY_BLOB;
/* Tags used for cryptographic parameters in keygen. Nothing to enforce. */
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
index 9e36ae6..440eb50 100644
--- a/keystore/legacy_keymaster_device_wrapper.cpp
+++ b/keystore/legacy_keymaster_device_wrapper.cpp
@@ -348,6 +348,24 @@
hidl_vec<hidl_vec<uint8_t>> resultCertChain;
+ for (size_t i = 0; i < attestParams.size(); ++i) {
+ switch (attestParams[i].tag) {
+ case Tag::ATTESTATION_ID_BRAND:
+ case Tag::ATTESTATION_ID_DEVICE:
+ case Tag::ATTESTATION_ID_PRODUCT:
+ case Tag::ATTESTATION_ID_SERIAL:
+ case Tag::ATTESTATION_ID_IMEI:
+ case Tag::ATTESTATION_ID_MEID:
+ // Device id attestation may only be supported if the device is able to permanently
+ // destroy its knowledge of the ids. This device is unable to do this, so it must
+ // never perform any device id attestation.
+ _hidl_cb(ErrorCode::CANNOT_ATTEST_IDS, resultCertChain);
+ return Void();
+ default:
+ break;
+ }
+ }
+
keymaster_cert_chain_t cert_chain = {};
auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
@@ -404,6 +422,10 @@
return legacy_enum_conversion(keymaster_device_->delete_all_keys(keymaster_device_));
}
+Return<ErrorCode> LegacyKeymasterDeviceWrapper::destroyAttestationIds() {
+ return ErrorCode::UNIMPLEMENTED;
+}
+
Return<void> LegacyKeymasterDeviceWrapper::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
const hidl_vec<KeyParameter>& inParams,
begin_cb _hidl_cb) {
diff --git a/keystore/legacy_keymaster_device_wrapper.h b/keystore/legacy_keymaster_device_wrapper.h
index 5712178..ad26221 100644
--- a/keystore/legacy_keymaster_device_wrapper.h
+++ b/keystore/legacy_keymaster_device_wrapper.h
@@ -68,6 +68,7 @@
upgradeKey_cb _hidl_cb) override;
Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
Return<ErrorCode> deleteAllKeys() override;
+ Return<ErrorCode> destroyAttestationIds() override;
Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) override;
Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,