Merge "Apply aidl_format to NNAPI AIDL interface files"
diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/DeviceInfo.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/DeviceInfo.aidl
index 00abff9..3e25c56 100644
--- a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/DeviceInfo.aidl
+++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/DeviceInfo.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *////////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/IMemtrack.aidl
index 844a1bb..2e2b68e 100644
--- a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/IMemtrack.aidl
+++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/IMemtrack.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *////////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackRecord.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackRecord.aidl
index 09ecefc..0e15ce3 100644
--- a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackRecord.aidl
+++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackRecord.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *////////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackType.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackType.aidl
index 7f3f939..b19869e 100644
--- a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackType.aidl
+++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackType.aidl
@@ -1,14 +1,29 @@
-///////////////////////////////////////////////////////////////////////////////
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *////////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -23,5 +38,4 @@
GRAPHICS = 2,
MULTIMEDIA = 3,
CAMERA = 4,
- NUM_TYPES = 5,
}
diff --git a/memtrack/aidl/android/hardware/memtrack/MemtrackType.aidl b/memtrack/aidl/android/hardware/memtrack/MemtrackType.aidl
index 715c6bf..5db735a 100644
--- a/memtrack/aidl/android/hardware/memtrack/MemtrackType.aidl
+++ b/memtrack/aidl/android/hardware/memtrack/MemtrackType.aidl
@@ -27,5 +27,4 @@
GRAPHICS = 2,
MULTIMEDIA = 3,
CAMERA = 4,
- NUM_TYPES,
}
diff --git a/memtrack/aidl/default/Memtrack.cpp b/memtrack/aidl/default/Memtrack.cpp
index 000b25c..49a6582 100644
--- a/memtrack/aidl/default/Memtrack.cpp
+++ b/memtrack/aidl/default/Memtrack.cpp
@@ -26,7 +26,8 @@
if (pid < 0) {
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
}
- if (type < MemtrackType::OTHER || type >= MemtrackType::NUM_TYPES) {
+ if (type != MemtrackType::OTHER && type != MemtrackType::GL && type != MemtrackType::GRAPHICS &&
+ type != MemtrackType::MULTIMEDIA && type != MemtrackType::CAMERA) {
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
}
_aidl_return->clear();
diff --git a/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp b/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp
index d5f4612..8905f50 100644
--- a/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp
+++ b/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp
@@ -46,17 +46,19 @@
TEST_P(MemtrackAidlTest, GetMemoryInvalidPid) {
int pid = -1;
- MemtrackType type = MemtrackType::OTHER;
- std::vector<MemtrackRecord> records;
- auto status = memtrack_->getMemory(pid, type, &records);
+ for (MemtrackType type : ndk::enum_range<MemtrackType>()) {
+ std::vector<MemtrackRecord> records;
- EXPECT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ auto status = memtrack_->getMemory(pid, type, &records);
+
+ EXPECT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ }
}
TEST_P(MemtrackAidlTest, GetMemoryInvalidType) {
int pid = 1;
- MemtrackType type = MemtrackType::NUM_TYPES;
+ MemtrackType type = static_cast<MemtrackType>(-1);
std::vector<MemtrackRecord> records;
auto status = memtrack_->getMemory(pid, type, &records);
@@ -66,12 +68,13 @@
TEST_P(MemtrackAidlTest, GetMemory) {
int pid = 1;
- MemtrackType type = MemtrackType::OTHER;
- std::vector<MemtrackRecord> records;
+ for (MemtrackType type : ndk::enum_range<MemtrackType>()) {
+ std::vector<MemtrackRecord> records;
- auto status = memtrack_->getMemory(pid, type, &records);
+ auto status = memtrack_->getMemory(pid, type, &records);
- EXPECT_TRUE(status.isOk());
+ EXPECT_TRUE(status.isOk());
+ }
}
TEST_P(MemtrackAidlTest, GetGpuDeviceInfo) {
@@ -87,7 +90,7 @@
->getRuntimeInfo(RuntimeInfo::FetchFlag::CPU_VERSION)
->kernelVersion();
EXPECT_LT(kernel_version, min_kernel_version)
- << "Devices with 5.10 or later kernels must implement getGpuDeviceInfo()";
+ << "Devices with 5.4 or later kernels must implement getGpuDeviceInfo()";
return;
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
index 132135b..9f4e509 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -43,5 +43,7 @@
void deleteAllKeys();
void destroyAttestationIds();
android.hardware.security.keymint.BeginResult begin(in android.hardware.security.keymint.KeyPurpose inPurpose, in byte[] inKeyBlob, in android.hardware.security.keymint.KeyParameter[] inParams, in android.hardware.security.keymint.HardwareAuthToken inAuthToken);
+ void deviceLocked(in boolean passwordOnly, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken);
+ void earlyBootEnded();
const int AUTH_TOKEN_MAC_LENGTH = 32;
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index 93966ea..d06312a 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -37,4 +37,5 @@
android.hardware.security.keymint.SecurityLevel securityLevel;
@utf8InCpp String keyMintName;
@utf8InCpp String keyMintAuthorName;
+ boolean timestampTokenRequired;
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 0120a30..71abedd 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -22,10 +22,11 @@
import android.hardware.security.keymint.IKeyMintOperation;
import android.hardware.security.keymint.KeyCreationResult;
import android.hardware.security.keymint.KeyFormat;
-import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.KeyMintHardwareInfo;
+import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.KeyPurpose;
import android.hardware.security.keymint.SecurityLevel;
+import android.hardware.security.secureclock.TimeStampToken;
/**
* KeyMint device definition.
@@ -346,8 +347,8 @@
*
* @return The result of key creation. See KeyCreationResult.aidl.
*/
- KeyCreationResult importKey(in KeyParameter[] keyParams, in KeyFormat keyFormat,
- in byte[] keyData);
+ KeyCreationResult importKey(
+ in KeyParameter[] keyParams, in KeyFormat keyFormat, in byte[] keyData);
/**
* Securely imports a key, or key pair, returning a key blob and a description of the imported
@@ -429,12 +430,9 @@
*
* @return The result of key creation. See KeyCreationResult.aidl.
*/
- KeyCreationResult importWrappedKey(in byte[] wrappedKeyData,
- in byte[] wrappingKeyBlob,
- in byte[] maskingKey,
- in KeyParameter[] unwrappingParams,
- in long passwordSid,
- in long biometricSid);
+ KeyCreationResult importWrappedKey(in byte[] wrappedKeyData, in byte[] wrappingKeyBlob,
+ in byte[] maskingKey, in KeyParameter[] unwrappingParams, in long passwordSid,
+ in long biometricSid);
/**
* Upgrades an old key blob. Keys can become "old" in two ways: IKeyMintDevice can be
@@ -705,8 +703,44 @@
* from operations that generate an IV or nonce, and IKeyMintOperation object pointer
* which is used to perform update(), finish() or abort() operations.
*/
- BeginResult begin(in KeyPurpose inPurpose,
- in byte[] inKeyBlob,
- in KeyParameter[] inParams,
- in HardwareAuthToken inAuthToken);
+ BeginResult begin(in KeyPurpose inPurpose, in byte[] inKeyBlob, in KeyParameter[] inParams,
+ in HardwareAuthToken inAuthToken);
+
+ /**
+ * Called by client to notify the IKeyMintDevice that the device is now locked, and keys with
+ * the UNLOCKED_DEVICE_REQUIRED tag should no longer be usable. When this function is called,
+ * the IKeyMintDevice should note the current timestamp, and attempts to use
+ * UNLOCKED_DEVICE_REQUIRED keys must be rejected with Error::DEVICE_LOCKED until an
+ * authentication token with a later timestamp is presented. If the `passwordOnly' argument is
+ * set to true the sufficiently-recent authentication token must indicate that the user
+ * authenticated with a password, not a biometric.
+ *
+ * Note that the IKeyMintDevice UNLOCKED_DEVICE_REQUIRED semantics are slightly different from
+ * the UNLOCKED_DEVICE_REQUIRED semantics enforced by keystore. Keystore handles device locking
+ * on a per-user basis. Because auth tokens do not contain an Android user ID, it's not
+ * possible to replicate the keystore enformcement logic in IKeyMintDevice. So from the
+ * IKeyMintDevice perspective, any user unlock unlocks all UNLOCKED_DEVICE_REQUIRED keys.
+ * Keystore will continue enforcing the per-user device locking.
+ *
+ * @param passwordOnly specifies whether the device must be unlocked with a password, rather
+ * than a biometric, before UNLOCKED_DEVICE_REQUIRED keys can be used.
+ *
+ * @param timestampToken is used by StrongBox implementations of IKeyMintDevice. It
+ * provides the StrongBox IKeyMintDevice with a fresh, MACed timestamp which it can use as the
+ * device-lock time, for future comparison against auth tokens when operations using
+ * UNLOCKED_DEVICE_REQUIRED keys are attempted. Unless the auth token timestamp is newer than
+ * the timestamp in the timestampToken, the device is still considered to be locked.
+ * Crucially, if a StrongBox IKeyMintDevice receives a deviceLocked() call with a timestampToken
+ * timestamp that is less than the timestamp in the last deviceLocked() call, it must ignore the
+ * new timestamp. TEE IKeyMintDevice implementations will receive an empty timestampToken (zero
+ * values and empty vectors) and should use their own clock as the device-lock time.
+ */
+ void deviceLocked(in boolean passwordOnly, in @nullable TimeStampToken timestampToken);
+
+ /**
+ * Called by client to notify the IKeyMintDevice that the device has left the early boot
+ * state, and that keys with the EARLY_BOOT_ONLY tag may no longer be used. All attempts to use
+ * an EARLY_BOOT_ONLY key after this method is called must fail with Error::INVALID_KEY_BLOB.
+ */
+ void earlyBootEnded();
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index 1a107ba..2fcaf4c 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -45,4 +45,11 @@
* same author.
*/
@utf8InCpp String keyMintAuthorName;
+
+ /* The timestampTokenRequired is a boolean flag, which when true reflects that IKeyMintDevice
+ * instance will expect a valid TimeStampToken with various operations. This will typically
+ * required by the StrongBox implementations that generally don't have secure clock hardware to
+ * generate timestamp tokens.
+ */
+ boolean timestampTokenRequired;
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 6555157..eb66aca 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -45,7 +45,7 @@
namespace test {
namespace {
-
+typedef KeyMintAidlTestBase::KeyData KeyData;
// Predicate for testing basic characteristics validity in generation or import.
bool KeyCharacteristicsBasicallyValid(SecurityLevel secLevel,
const vector<KeyCharacteristics>& key_characteristics) {
@@ -461,6 +461,34 @@
}
}
+auto KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
+ const string& message, const AuthorizationSet& in_params)
+ -> std::tuple<ErrorCode, string, AuthorizationSet /* out_params */> {
+ AuthorizationSet begin_out_params;
+ ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
+ AuthorizationSet out_params(std::move(begin_out_params));
+ if (result != ErrorCode::OK) {
+ return {result, {}, out_params};
+ }
+
+ string output;
+ int32_t consumed = 0;
+ AuthorizationSet update_params;
+ AuthorizationSet update_out_params;
+ result = Update(update_params, message, &update_out_params, &output, &consumed);
+ out_params.push_back(update_out_params);
+ if (result != ErrorCode::OK) {
+ return {result, output, out_params};
+ }
+
+ string unused;
+ AuthorizationSet finish_params;
+ AuthorizationSet finish_out_params;
+ result = Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output);
+ out_params.push_back(finish_out_params);
+ return {result, output, out_params};
+}
+
string KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
const string& message, const AuthorizationSet& in_params,
AuthorizationSet* out_params) {
@@ -859,6 +887,35 @@
return authList;
}
+ErrorCode KeyMintAidlTestBase::UseAesKey(const vector<uint8_t>& aesKeyBlob) {
+ auto [result, ciphertext, out_params] = ProcessMessage(
+ aesKeyBlob, KeyPurpose::ENCRYPT, "1234567890123456",
+ AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE));
+ return result;
+}
+
+ErrorCode KeyMintAidlTestBase::UseHmacKey(const vector<uint8_t>& hmacKeyBlob) {
+ auto [result, mac, out_params] = ProcessMessage(
+ hmacKeyBlob, KeyPurpose::SIGN, "1234567890123456",
+ AuthorizationSetBuilder().Authorization(TAG_MAC_LENGTH, 128).Digest(Digest::SHA_2_256));
+ return result;
+}
+
+ErrorCode KeyMintAidlTestBase::UseRsaKey(const vector<uint8_t>& rsaKeyBlob) {
+ std::string message(2048 / 8, 'a');
+ auto [result, signature, out_params] = ProcessMessage(
+ rsaKeyBlob, KeyPurpose::SIGN, message,
+ AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
+ return result;
+}
+
+ErrorCode KeyMintAidlTestBase::UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob) {
+ auto [result, signature, out_params] =
+ ProcessMessage(ecdsaKeyBlob, KeyPurpose::SIGN, "a",
+ AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
+ return result;
+}
+
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 780971d..4e546ed 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -43,6 +43,11 @@
class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
public:
+ struct KeyData {
+ vector<uint8_t> blob;
+ vector<KeyCharacteristics> characteristics;
+ };
+
void SetUp() override;
void TearDown() override {
if (key_blob_.size()) {
@@ -61,7 +66,6 @@
vector<KeyCharacteristics>* key_characteristics);
ErrorCode GenerateKey(const AuthorizationSet& key_desc);
-
ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
const string& key_material, vector<uint8_t>* key_blob,
vector<KeyCharacteristics>* key_characteristics);
@@ -106,7 +110,9 @@
string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
const string& message, const AuthorizationSet& in_params,
AuthorizationSet* out_params);
-
+ std::tuple<ErrorCode, std::string /* processedMessage */, AuthorizationSet /* out_params */>
+ ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
+ const std::string& message, const AuthorizationSet& in_params);
string SignMessage(const vector<uint8_t>& key_blob, const string& message,
const AuthorizationSet& params);
string SignMessage(const string& message, const AuthorizationSet& params);
@@ -149,6 +155,56 @@
std::pair<ErrorCode, vector<uint8_t>> UpgradeKey(const vector<uint8_t>& key_blob);
+ template <typename TagType>
+ std::tuple<KeyData /* aesKey */, KeyData /* hmacKey */, KeyData /* rsaKey */,
+ KeyData /* ecdsaKey */>
+ CreateTestKeys(TagType tagToTest, ErrorCode expectedReturn) {
+ /* AES */
+ KeyData aesKeyData;
+ ErrorCode errorCode = GenerateKey(AuthorizationSetBuilder()
+ .AesEncryptionKey(128)
+ .Authorization(tagToTest)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED),
+ &aesKeyData.blob, &aesKeyData.characteristics);
+ EXPECT_EQ(expectedReturn, errorCode);
+
+ /* HMAC */
+ KeyData hmacKeyData;
+ errorCode = GenerateKey(AuthorizationSetBuilder()
+ .HmacKey(128)
+ .Authorization(tagToTest)
+ .Digest(Digest::SHA_2_256)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Authorization(TAG_NO_AUTH_REQUIRED),
+ &hmacKeyData.blob, &hmacKeyData.characteristics);
+ EXPECT_EQ(expectedReturn, errorCode);
+
+ /* RSA */
+ KeyData rsaKeyData;
+ errorCode = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Authorization(tagToTest)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ &rsaKeyData.blob, &rsaKeyData.characteristics);
+ EXPECT_EQ(expectedReturn, errorCode);
+
+ /* ECDSA */
+ KeyData ecdsaKeyData;
+ errorCode = GenerateKey(AuthorizationSetBuilder()
+ .EcdsaSigningKey(256)
+ .Authorization(tagToTest)
+ .Digest(Digest::SHA_2_256)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ &ecdsaKeyData.blob, &ecdsaKeyData.characteristics);
+ EXPECT_EQ(expectedReturn, errorCode);
+ return {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData};
+ }
bool IsSecure() const { return securityLevel_ != SecurityLevel::SOFTWARE; }
SecurityLevel SecLevel() const { return securityLevel_; }
@@ -182,6 +238,10 @@
const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(
const vector<KeyCharacteristics>& key_characteristics);
+ ErrorCode UseAesKey(const vector<uint8_t>& aesKeyBlob);
+ ErrorCode UseHmacKey(const vector<uint8_t>& hmacKeyBlob);
+ ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
+ ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob);
private:
std::shared_ptr<IKeyMintDevice> keymint_;
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 88122ce..7801ed1 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -78,7 +78,8 @@
namespace {
template <TagType tag_type, Tag tag, typename ValueT>
-bool contains(vector<KeyParameter>& set, TypedTag<tag_type, tag> ttag, ValueT expected_value) {
+bool contains(const vector<KeyParameter>& set, TypedTag<tag_type, tag> ttag,
+ ValueT expected_value) {
auto it = std::find_if(set.begin(), set.end(), [&](const KeyParameter& param) {
if (auto p = authorizationValue(ttag, param)) {
return *p == expected_value;
@@ -89,7 +90,7 @@
}
template <TagType tag_type, Tag tag>
-bool contains(vector<KeyParameter>& set, TypedTag<tag_type, tag>) {
+bool contains(const vector<KeyParameter>& set, TypedTag<tag_type, tag>) {
auto it = std::find_if(set.begin(), set.end(),
[&](const KeyParameter& param) { return param.tag == tag; });
return (it != set.end());
@@ -4596,6 +4597,57 @@
}
}
+/*
+ * UsageCountLimitTest.TestSingleUseKeyAndRollbackResistance
+ *
+ * Verifies that when rollback resistance is supported by the KeyMint implementation with
+ * the secure hardware, the single use key with usage count limit tag = 1 must also be enforced
+ * in hardware.
+ */
+TEST_P(UsageCountLimitTest, TestSingleUseKeyAndRollbackResistance) {
+ if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+ auto error = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_ROLLBACK_RESISTANCE)
+ .SetDefaultValidity());
+ ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
+
+ if (error == ErrorCode::OK) {
+ // Rollback resistance is supported by KeyMint, verify it is enforced in hardware.
+ AuthorizationSet hardwareEnforced(SecLevelAuthorizations());
+ ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
+ ASSERT_EQ(ErrorCode::OK, DeleteKey());
+
+ // The KeyMint should also enforce single use key in hardware when it supports rollback
+ // resistance.
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaSigningKey(1024, 65537)
+ .NoDigestOrPadding()
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1)
+ .SetDefaultValidity()));
+
+ // Check the usage count limit tag appears in the hardware authorizations.
+ AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_);
+ EXPECT_TRUE(hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+ << "key usage count limit " << 1U << " missing";
+
+ string message = "1234567890123456";
+ auto params = AuthorizationSetBuilder().NoDigestOrPadding();
+
+ // First usage of RSA key should work.
+ SignMessage(message, params);
+
+ // Usage count limit tag is enforced by hardware. After using the key, the key blob
+ // must be invalidated from secure storage (such as RPMB partition).
+ EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, params));
+ }
+}
+
INSTANTIATE_KEYMINT_AIDL_TEST(UsageCountLimitTest);
typedef KeyMintAidlTestBase AddEntropyTest;
@@ -4645,7 +4697,8 @@
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_ROLLBACK_RESISTANCE));
+ .Authorization(TAG_ROLLBACK_RESISTANCE)
+ .SetDefaultValidity());
ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
// Delete must work if rollback protection is implemented
@@ -4678,7 +4731,8 @@
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_ROLLBACK_RESISTANCE));
+ .Authorization(TAG_ROLLBACK_RESISTANCE)
+ .SetDefaultValidity());
ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
// Delete must work if rollback protection is implemented
@@ -4961,6 +5015,99 @@
INSTANTIATE_KEYMINT_AIDL_TEST(KeyAgreementTest);
+typedef KeyMintAidlTestBase EarlyBootKeyTest;
+
+TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) {
+ auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
+ CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK);
+
+ CheckedDeleteKey(&aesKeyData.blob);
+ CheckedDeleteKey(&hmacKeyData.blob);
+ CheckedDeleteKey(&rsaKeyData.blob);
+ CheckedDeleteKey(&ecdsaKeyData.blob);
+}
+
+// This is a more comprenhensive test, but it can only be run on a machine which is still in early
+// boot stage, which no proper Android device is by the time we can run VTS. To use this,
+// un-disable it and modify vold to remove the call to earlyBootEnded(). Running the test will end
+// early boot, so you'll have to reboot between runs.
+TEST_P(EarlyBootKeyTest, DISABLED_FullTest) {
+ auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
+ CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK);
+ // TAG_EARLY_BOOT_ONLY should be in hw-enforced.
+ EXPECT_TRUE(HwEnforcedAuthorizations(aesKeyData.characteristics).Contains(TAG_EARLY_BOOT_ONLY));
+ EXPECT_TRUE(
+ HwEnforcedAuthorizations(hmacKeyData.characteristics).Contains(TAG_EARLY_BOOT_ONLY));
+ EXPECT_TRUE(HwEnforcedAuthorizations(rsaKeyData.characteristics).Contains(TAG_EARLY_BOOT_ONLY));
+ EXPECT_TRUE(
+ HwEnforcedAuthorizations(ecdsaKeyData.characteristics).Contains(TAG_EARLY_BOOT_ONLY));
+
+ // Should be able to use keys, since early boot has not ended
+ EXPECT_EQ(ErrorCode::OK, UseAesKey(aesKeyData.blob));
+ EXPECT_EQ(ErrorCode::OK, UseHmacKey(hmacKeyData.blob));
+ EXPECT_EQ(ErrorCode::OK, UseRsaKey(rsaKeyData.blob));
+ EXPECT_EQ(ErrorCode::OK, UseEcdsaKey(ecdsaKeyData.blob));
+
+ // End early boot
+ ErrorCode earlyBootResult = GetReturnErrorCode(keyMint().earlyBootEnded());
+ EXPECT_EQ(earlyBootResult, ErrorCode::OK);
+
+ // Should not be able to use already-created keys.
+ EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, UseAesKey(aesKeyData.blob));
+ EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, UseHmacKey(hmacKeyData.blob));
+ EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, UseRsaKey(rsaKeyData.blob));
+ EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, UseEcdsaKey(ecdsaKeyData.blob));
+
+ CheckedDeleteKey(&aesKeyData.blob);
+ CheckedDeleteKey(&hmacKeyData.blob);
+ CheckedDeleteKey(&rsaKeyData.blob);
+ CheckedDeleteKey(&ecdsaKeyData.blob);
+
+ // Should not be able to create new keys
+ std::tie(aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData) =
+ CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::EARLY_BOOT_ENDED);
+
+ CheckedDeleteKey(&aesKeyData.blob);
+ CheckedDeleteKey(&hmacKeyData.blob);
+ CheckedDeleteKey(&rsaKeyData.blob);
+ CheckedDeleteKey(&ecdsaKeyData.blob);
+}
+INSTANTIATE_KEYMINT_AIDL_TEST(EarlyBootKeyTest);
+
+typedef KeyMintAidlTestBase UnlockedDeviceRequiredTest;
+
+// This may be a problematic test. It can't be run repeatedly without unlocking the device in
+// between runs... and on most test devices there are no enrolled credentials so it can't be
+// unlocked at all, meaning the only way to get the test to pass again on a properly-functioning
+// device is to reboot it. For that reason, this is disabled by default. It can be used as part of
+// a manual test process, which includes unlocking between runs, which is why it's included here.
+// Well, that and the fact that it's the only test we can do without also making calls into the
+// Gatekeeper HAL. We haven't written any cross-HAL tests, and don't know what all of the
+// implications might be, so that may or may not be a solution.
+TEST_P(UnlockedDeviceRequiredTest, DISABLED_KeysBecomeUnusable) {
+ auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
+ CreateTestKeys(TAG_UNLOCKED_DEVICE_REQUIRED, ErrorCode::OK);
+
+ EXPECT_EQ(ErrorCode::OK, UseAesKey(aesKeyData.blob));
+ EXPECT_EQ(ErrorCode::OK, UseHmacKey(hmacKeyData.blob));
+ EXPECT_EQ(ErrorCode::OK, UseRsaKey(rsaKeyData.blob));
+ EXPECT_EQ(ErrorCode::OK, UseEcdsaKey(ecdsaKeyData.blob));
+
+ ErrorCode rc = GetReturnErrorCode(
+ keyMint().deviceLocked(false /* passwordOnly */, {} /* verificationToken */));
+ ASSERT_EQ(ErrorCode::OK, rc);
+ EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseAesKey(aesKeyData.blob));
+ EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseHmacKey(hmacKeyData.blob));
+ EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseRsaKey(rsaKeyData.blob));
+ EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseEcdsaKey(ecdsaKeyData.blob));
+
+ CheckedDeleteKey(&aesKeyData.blob);
+ CheckedDeleteKey(&hmacKeyData.blob);
+ CheckedDeleteKey(&rsaKeyData.blob);
+ CheckedDeleteKey(&ecdsaKeyData.blob);
+}
+INSTANTIATE_KEYMINT_AIDL_TEST(UnlockedDeviceRequiredTest);
+
} // namespace aidl::android::hardware::security::keymint::test
int main(int argc, char** argv) {