Merge "Improve unique attestation docs & tests"
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 362ab41..615fde0 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -496,10 +496,26 @@
* - program changes exactly to what was requested.
*/
TEST_P(BroadcastRadioHalTest, DabTune) {
+ Result halResult;
+ hidl_vec<DabTableEntry> config;
+ auto cb = [&](Result result, hidl_vec<DabTableEntry> configCb) {
+ halResult = result;
+ config = configCb;
+ };
+ auto hidlResult = mModule->getDabRegionConfig(cb);
+ ASSERT_TRUE(hidlResult.isOk());
+
+ if (halResult == Result::NOT_SUPPORTED) {
+ printSkipped("DAB not supported");
+ return;
+ }
+ ASSERT_EQ(Result::OK, halResult);
+ ASSERT_NE(config.size(), 0U);
+
ASSERT_TRUE(openSession());
ProgramSelector sel = {};
- uint64_t freq = 178352;
+ uint64_t freq = config[config.size() / 2].frequency;
sel.primaryId = make_identifier(IdentifierType::DAB_FREQUENCY,freq);
std::this_thread::sleep_for(gTuneWorkaround);
diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl
index 0327796..cf7048b 100644
--- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl
+++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl
@@ -1,3 +1,18 @@
+/*
+ * Copyright 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. //
///////////////////////////////////////////////////////////////////////////////
diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl
index 56f1de3..add4b64 100644
--- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl
+++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl
@@ -1,3 +1,18 @@
+/*
+ * Copyright 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. //
///////////////////////////////////////////////////////////////////////////////
@@ -18,7 +33,7 @@
package android.hardware.common.fmq;
@VintfStability
-parcelable MQDescriptor {
+parcelable MQDescriptor<T, Flavor> {
android.hardware.common.fmq.GrantorDescriptor[] grantors;
android.hardware.common.NativeHandle handle;
int quantum;
diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl
index 264171d..12c61ba 100644
--- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl
+++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl
@@ -1,3 +1,18 @@
+/*
+ * Copyright 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. //
///////////////////////////////////////////////////////////////////////////////
diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl
index eaf2ffd..f99528d 100644
--- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl
+++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl
@@ -1,3 +1,18 @@
+/*
+ * Copyright 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. //
///////////////////////////////////////////////////////////////////////////////
diff --git a/current.txt b/current.txt
index cd1446d..88b067d 100644
--- a/current.txt
+++ b/current.txt
@@ -836,4 +836,7 @@
ead4ec8713a2cb40906fe31ba793d21a6b1190143c446690d16a6ea686aa2fea android.hardware.tetheroffload.control@1.1::ITetheringOffloadCallback
e34b4c7bec5e032c14804707ca924dd6b99ed5ba139da7505fe7d698d0fe178f android.hardware.tetheroffload.control@1.1::types
+# ABI preserving changes to HALs during Android T
+62ace52d9c3ff1f60f94118557a2aaf0b953513e59dcd34d5f94ae28d4c7e780 android.hardware.fastboot@1.0::IFastboot
+
# There should be no more HIDL HALs - please use AIDL instead.
diff --git a/fastboot/1.0/IFastboot.hal b/fastboot/1.0/IFastboot.hal
index dce3ad7..b39061c 100644
--- a/fastboot/1.0/IFastboot.hal
+++ b/fastboot/1.0/IFastboot.hal
@@ -33,7 +33,7 @@
/**
* Executes a fastboot OEM command.
*
- * @param oemCmdArgs The oem command that is passed to the fastboot HAL.
+ * @param oemCmd The oem command that is passed to the fastboot HAL.
* @return result Returns the status SUCCESS if the operation is successful,
* INVALID_ARGUMENT for bad arguments,
* FAILURE_UNKNOWN for an invalid/unsupported command.
diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp
index 25f129b..200ee61 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.cpp
+++ b/identity/aidl/default/common/WritableIdentityCredential.cpp
@@ -210,6 +210,15 @@
"numAccessControlProfileRemaining_ is not zero"));
}
+ // Ensure passed-in profile ids reference valid access control profiles
+ for (const int32_t id : accessControlProfileIds) {
+ if (accessControlProfileIds_.find(id) == accessControlProfileIds_.end()) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+ IIdentityCredentialStore::STATUS_INVALID_DATA,
+ "An id in accessControlProfileIds references non-existing ACP"));
+ }
+ }
+
if (remainingEntryCounts_.size() == 0) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_INVALID_DATA, "No more namespaces to add to"));
diff --git a/identity/aidl/vts/DeleteCredentialTests.cpp b/identity/aidl/vts/DeleteCredentialTests.cpp
index d3addf4..7627c9c 100644
--- a/identity/aidl/vts/DeleteCredentialTests.cpp
+++ b/identity/aidl/vts/DeleteCredentialTests.cpp
@@ -102,7 +102,7 @@
ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
// Single entry - don't care about the returned encrypted data
- ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk());
+ ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk());
vector<uint8_t> encryptedData;
ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk());
diff --git a/identity/aidl/vts/ProveOwnershipTests.cpp b/identity/aidl/vts/ProveOwnershipTests.cpp
index fa0e293..c622193 100644
--- a/identity/aidl/vts/ProveOwnershipTests.cpp
+++ b/identity/aidl/vts/ProveOwnershipTests.cpp
@@ -102,7 +102,7 @@
ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
// Single entry - don't care about the returned encrypted data
- ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk());
+ ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk());
vector<uint8_t> encryptedData;
ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk());
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 4547624..7f4674d 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -644,7 +644,7 @@
// the VTS tests. Of course, this is a pretend-only game since hopefully no
// relying party is ever going to trust our batch key and those keys above
// it.
- ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMASTER_4_1,
+ ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1,
KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT);
keymaster_error_t error;
@@ -682,10 +682,9 @@
i2d_X509_NAME(subjectName.get(), &subjectPtr);
- uint64_t nowMilliSeconds = time(nullptr) * 1000;
::keymaster::AuthorizationSet auth_set(
::keymaster::AuthorizationSetBuilder()
- .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, nowMilliSeconds)
+ .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds)
.Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds)
.Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
challenge.size())
diff --git a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
index e0b529f..94ce5c1 100644
--- a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
@@ -357,16 +357,40 @@
return false;
}
+ // If fallbackModel is not provided, call prepareModelFromCache.
+ // If fallbackModel is provided, and prepareModelFromCache returns GENERAL_FAILURE,
+ // then prepareModel(fallbackModel) will be called.
+ // This replicates the behaviour of the runtime when loading a model from cache.
+ // NNAPI Shim depends on this behaviour and may try to load the model from cache in
+ // prepareModel (shim needs model information when loading from cache).
void prepareModelFromCache(const std::vector<ndk::ScopedFileDescriptor>& modelCache,
const std::vector<ndk::ScopedFileDescriptor>& dataCache,
- std::shared_ptr<IPreparedModel>* preparedModel,
- ErrorStatus* status) {
+ std::shared_ptr<IPreparedModel>* preparedModel, ErrorStatus* status,
+ const Model* fallbackModel = nullptr) {
// Launch prepare model from cache.
std::shared_ptr<PreparedModelCallback> preparedModelCallback =
ndk::SharedRefBase::make<PreparedModelCallback>();
std::vector<uint8_t> cacheToken(std::begin(mToken), std::end(mToken));
- const auto prepareLaunchStatus = kDevice->prepareModelFromCache(
+ auto prepareLaunchStatus = kDevice->prepareModelFromCache(
kNoDeadline, modelCache, dataCache, cacheToken, preparedModelCallback);
+
+ // The shim does not support prepareModelFromCache() properly, but it
+ // will still attempt to create a model from cache when modelCache or
+ // dataCache is provided in prepareModel(). Instead of failing straight
+ // away, we try to utilize that other code path when fallbackModel is
+ // set. Note that we cannot verify whether the returned model was
+ // actually prepared from cache in that case.
+ if (!prepareLaunchStatus.isOk() &&
+ prepareLaunchStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+ static_cast<ErrorStatus>(prepareLaunchStatus.getServiceSpecificError()) ==
+ ErrorStatus::GENERAL_FAILURE &&
+ mIsCachingSupported && fallbackModel != nullptr) {
+ preparedModelCallback = ndk::SharedRefBase::make<PreparedModelCallback>();
+ prepareLaunchStatus = kDevice->prepareModel(
+ *fallbackModel, ExecutionPreference::FAST_SINGLE_ANSWER, kDefaultPriority,
+ kNoDeadline, modelCache, dataCache, cacheToken, preparedModelCallback);
+ }
+
ASSERT_TRUE(prepareLaunchStatus.isOk() ||
prepareLaunchStatus.getExceptionCode() == EX_SERVICE_SPECIFIC)
<< "prepareLaunchStatus: " << prepareLaunchStatus.getDescription();
@@ -382,6 +406,42 @@
*preparedModel = preparedModelCallback->getPreparedModel();
}
+ // Replicate behaviour of runtime when loading model from cache.
+ // Test if prepareModelFromCache behaves correctly when faced with bad
+ // arguments. If prepareModelFromCache is not supported (GENERAL_FAILURE),
+ // it attempts to call prepareModel with same arguments, which is expected either
+ // to not support the model (GENERAL_FAILURE) or return a valid model.
+ void verifyModelPreparationBehaviour(const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+ const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+ const Model* model, const TestModel& testModel) {
+ std::shared_ptr<IPreparedModel> preparedModel;
+ ErrorStatus status;
+
+ // Verify that prepareModelFromCache fails either due to bad
+ // arguments (INVALID_ARGUMENT) or GENERAL_FAILURE if not supported.
+ prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+ /*fallbackModel=*/nullptr);
+ if (status != ErrorStatus::INVALID_ARGUMENT) {
+ ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
+ }
+ ASSERT_EQ(preparedModel, nullptr);
+
+ // If caching is not supported, attempt calling prepareModel.
+ if (status == ErrorStatus::GENERAL_FAILURE) {
+ // Fallback with prepareModel should succeed regardless of cache files
+ prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+ /*fallbackModel=*/model);
+ // Unless caching is not supported?
+ if (status != ErrorStatus::GENERAL_FAILURE) {
+ // But if it is, we should see a valid model.
+ ASSERT_EQ(status, ErrorStatus::NONE);
+ ASSERT_NE(preparedModel, nullptr);
+ EvaluatePreparedModel(kDevice, preparedModel, testModel,
+ /*testKind=*/TestKind::GENERAL);
+ }
+ }
+ }
+
// Absolute path to the temporary cache directory.
std::string mCacheDir;
@@ -397,7 +457,7 @@
uint8_t mToken[static_cast<uint32_t>(IDevice::BYTE_SIZE_OF_CACHE_TOKEN)] = {};
uint32_t mNumModelCache;
uint32_t mNumDataCache;
- uint32_t mIsCachingSupported;
+ bool mIsCachingSupported;
const std::shared_ptr<IDevice> kDevice;
// The primary data type of the testModel.
@@ -438,7 +498,8 @@
std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
+ prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+ /*fallbackModel=*/&model);
if (!mIsCachingSupported) {
ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
ASSERT_EQ(preparedModel, nullptr);
@@ -498,7 +559,8 @@
for (uint32_t i = 0; i < dataCache.size(); i++) {
ASSERT_GE(read(dataCache[i].get(), &placeholderByte, 1), 0);
}
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
+ prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+ /*fallbackModel=*/&model);
if (!mIsCachingSupported) {
ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
ASSERT_EQ(preparedModel, nullptr);
@@ -536,13 +598,7 @@
// Execute and verify results.
EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
- preparedModel = nullptr;
- ErrorStatus status;
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::INVALID_ARGUMENT) {
- ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
- }
- ASSERT_EQ(preparedModel, nullptr);
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
// Test with number of model cache files smaller than mNumModelCache.
@@ -560,13 +616,7 @@
// Execute and verify results.
EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
- preparedModel = nullptr;
- ErrorStatus status;
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::INVALID_ARGUMENT) {
- ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
- }
- ASSERT_EQ(preparedModel, nullptr);
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
// Test with number of data cache files greater than mNumDataCache.
@@ -583,13 +633,7 @@
// Execute and verify results.
EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
- preparedModel = nullptr;
- ErrorStatus status;
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::INVALID_ARGUMENT) {
- ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
- }
- ASSERT_EQ(preparedModel, nullptr);
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
// Test with number of data cache files smaller than mNumDataCache.
@@ -607,13 +651,7 @@
// Execute and verify results.
EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
- preparedModel = nullptr;
- ErrorStatus status;
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::INVALID_ARGUMENT) {
- ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
- }
- ASSERT_EQ(preparedModel, nullptr);
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
}
@@ -633,68 +671,48 @@
// Test with number of model cache files greater than mNumModelCache.
{
- std::shared_ptr<IPreparedModel> preparedModel = nullptr;
- ErrorStatus status;
std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
mModelCache.push_back({mTmpCache});
createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
mModelCache.pop_back();
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::GENERAL_FAILURE) {
- ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT);
- }
- ASSERT_EQ(preparedModel, nullptr);
+
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
// Test with number of model cache files smaller than mNumModelCache.
if (mModelCache.size() > 0) {
- std::shared_ptr<IPreparedModel> preparedModel = nullptr;
- ErrorStatus status;
std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
auto tmp = mModelCache.back();
mModelCache.pop_back();
createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
mModelCache.push_back(tmp);
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::GENERAL_FAILURE) {
- ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT);
- }
- ASSERT_EQ(preparedModel, nullptr);
+
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
// Test with number of data cache files greater than mNumDataCache.
{
- std::shared_ptr<IPreparedModel> preparedModel = nullptr;
- ErrorStatus status;
std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
mDataCache.push_back({mTmpCache});
createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
mDataCache.pop_back();
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::GENERAL_FAILURE) {
- ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT);
- }
- ASSERT_EQ(preparedModel, nullptr);
+
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
// Test with number of data cache files smaller than mNumDataCache.
if (mDataCache.size() > 0) {
- std::shared_ptr<IPreparedModel> preparedModel = nullptr;
- ErrorStatus status;
std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
auto tmp = mDataCache.back();
mDataCache.pop_back();
createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
mDataCache.push_back(tmp);
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::GENERAL_FAILURE) {
- ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT);
- }
- ASSERT_EQ(preparedModel, nullptr);
+
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
}
@@ -719,13 +737,7 @@
// Execute and verify results.
EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
- preparedModel = nullptr;
- ErrorStatus status;
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::INVALID_ARGUMENT) {
- ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
- }
- ASSERT_EQ(preparedModel, nullptr);
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
// Go through each handle in data cache, test with invalid access mode.
@@ -741,13 +753,7 @@
// Execute and verify results.
EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
- preparedModel = nullptr;
- ErrorStatus status;
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- if (status != ErrorStatus::INVALID_ARGUMENT) {
- ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
- }
- ASSERT_EQ(preparedModel, nullptr);
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
}
@@ -769,30 +775,23 @@
// Go through each handle in model cache, test with invalid access mode.
for (uint32_t i = 0; i < mNumModelCache; i++) {
- std::shared_ptr<IPreparedModel> preparedModel = nullptr;
- ErrorStatus status;
std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
modelCacheMode[i] = AccessMode::WRITE_ONLY;
createCacheFds(mModelCache, modelCacheMode, &modelCache);
createCacheFds(mDataCache, dataCacheMode, &dataCache);
modelCacheMode[i] = AccessMode::READ_WRITE;
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
- ASSERT_EQ(preparedModel, nullptr);
+
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
// Go through each handle in data cache, test with invalid access mode.
for (uint32_t i = 0; i < mNumDataCache; i++) {
- std::shared_ptr<IPreparedModel> preparedModel = nullptr;
- ErrorStatus status;
std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
dataCacheMode[i] = AccessMode::WRITE_ONLY;
createCacheFds(mModelCache, modelCacheMode, &modelCache);
createCacheFds(mDataCache, dataCacheMode, &dataCache);
dataCacheMode[i] = AccessMode::READ_WRITE;
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
- ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
- ASSERT_EQ(preparedModel, nullptr);
+ verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
}
}
@@ -872,7 +871,8 @@
std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
+ prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+ /*fallbackModel=*/nullptr);
// The preparation may fail or succeed, but must not crash. If the preparation succeeds,
// the prepared model must be executed with the correct result and not crash.
@@ -933,7 +933,8 @@
// Spawn a thread to copy the cache content concurrently while preparing from cache.
std::thread thread(copyCacheFiles, std::cref(modelCacheMul), std::cref(mModelCache));
- prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
+ prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+ /*fallbackModel=*/nullptr);
thread.join();
// The preparation may fail or succeed, but must not crash. If the preparation succeeds,
diff --git a/radio/1.0/vts/functional/vts_test_util.cpp b/radio/1.0/vts/functional/vts_test_util.cpp
index fc37201..5b31acc 100644
--- a/radio/1.0/vts/functional/vts_test_util.cpp
+++ b/radio/1.0/vts/functional/vts_test_util.cpp
@@ -83,6 +83,13 @@
return hasFeature;
}
+bool isSsSsEnabled() {
+ // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "")
+ // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e.
+ // by definition the empty string "" is a substring of any string).
+ return !isDsDsEnabled() && !isTsTsEnabled();
+}
+
bool isDsDsEnabled() {
return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "dsds");
}
diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h
index eeb1d29..fa338a3 100644
--- a/radio/1.0/vts/functional/vts_test_util.h
+++ b/radio/1.0/vts/functional/vts_test_util.h
@@ -80,12 +80,17 @@
bool deviceSupportsFeature(const char* feature);
/*
- * Check if device is in DSDS.
+ * Check if device is in SsSs (Single SIM Single Standby).
+ */
+bool isSsSsEnabled();
+
+/*
+ * Check if device is in DSDS (Dual SIM Dual Standby).
*/
bool isDsDsEnabled();
/*
- * Check if device is in TSTS.
+ * Check if device is in TSTS (Triple SIM Triple Standby).
*/
bool isTsTsEnabled();
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 422e91c..34395ca 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -821,7 +821,7 @@
/*
* Test IRadio.updateSimPhonebookRecords() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_6, updateSimPhonebookRecords) {
+TEST_P(RadioHidlTest_v1_6, updateSimPhonebookRecords) {
serial = GetRandomSerialNumber();
radio_v1_6->getSimPhonebookCapacity(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -851,7 +851,11 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
- EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED},
+ CHECK_GENERAL_ERROR));
if(pbCapacity.maxAdnRecords > 0
&& pbCapacity.usedAdnRecords < pbCapacity.maxAdnRecords) {
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
index 5d514a0..00f4468 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -16,8 +16,39 @@
#include <radio_hidl_hal_utils_v1_6.h>
+bool isServiceValidForDeviceConfiguration(hidl_string& serviceName) {
+ if (isSsSsEnabled()) {
+ // Device is configured as SSSS.
+ if (serviceName != RADIO_SERVICE_SLOT1_NAME) {
+ ALOGI("%s instance is not valid for SSSS device.", serviceName.c_str());
+ return false;
+ }
+ } else if (isDsDsEnabled()) {
+ // Device is configured as DSDS.
+ if (serviceName != RADIO_SERVICE_SLOT1_NAME && serviceName != RADIO_SERVICE_SLOT2_NAME) {
+ ALOGI("%s instance is not valid for DSDS device.", serviceName.c_str());
+ return false;
+ }
+ } else if (isTsTsEnabled()) {
+ // Device is configured as TSTS.
+ if (serviceName != RADIO_SERVICE_SLOT1_NAME && serviceName != RADIO_SERVICE_SLOT2_NAME &&
+ serviceName != RADIO_SERVICE_SLOT3_NAME) {
+ ALOGI("%s instance is not valid for TSTS device.", serviceName.c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
void RadioHidlTest_v1_6::SetUp() {
- radio_v1_6 = android::hardware::radio::V1_6::IRadio::getService(GetParam());
+ hidl_string serviceName = GetParam();
+
+ if (!isServiceValidForDeviceConfiguration(serviceName)) {
+ ALOGI("Skipped the test due to device configuration.");
+ GTEST_SKIP();
+ }
+
+ radio_v1_6 = android::hardware::radio::V1_6::IRadio::getService(serviceName);
ASSERT_NE(nullptr, radio_v1_6.get());
radioRsp_v1_6 = new (std::nothrow) RadioResponse_v1_6(*this);
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 3185f98..54c2977 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -48,7 +48,9 @@
#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
-#define RADIO_SERVICE_NAME "slot1"
+#define RADIO_SERVICE_SLOT1_NAME "slot1" // HAL instance name for SIM slot 1 or single SIM device
+#define RADIO_SERVICE_SLOT2_NAME "slot2" // HAL instance name for SIM slot 2 on dual SIM device
+#define RADIO_SERVICE_SLOT3_NAME "slot3" // HAL instance name for SIM slot 3 on triple SIM device
class RadioHidlTest_v1_6;
extern ::android::hardware::radio::V1_5::CardStatus cardStatus;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 9cc795d..5b0b303 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -805,9 +805,10 @@
byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob);
/**
- * Returns parameters associated with the provided key. This should match the
- * KeyCharacteristics present in the KeyCreationResult returned by generateKey(),
- * importKey(), or importWrappedKey().
+ * Returns KeyMint-enforced parameters associated with the provided key. The returned tags are
+ * a subset of KeyCharacteristics found in the KeyCreationResult returned by generateKey(),
+ * importKey(), or importWrappedKey(). The returned value is a subset, as it does not include
+ * any Keystore-enforced parameters.
*
* @param keyBlob The opaque descriptor returned by generateKey, importKey or importWrappedKey.
*
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index aa7b492..ce83044 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -155,8 +155,7 @@
* it must process all but the tag length and buffer the possible tag data for processing during
* finish().
*
- * @param input Data to be processed. Note that update() may or may not consume all of the data
- * provided. See return value.
+ * @param input Data to be processed. update() must consume all input data.
*
* @param authToken Authentication token. Can be nullable if not provided.
*
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index d5c45e2..ff08ce6 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -37,15 +37,15 @@
shared_libs: [
"libbinder_ndk",
"libcrypto",
- "libkeymint",
- "libkeymint_support",
],
static_libs: [
"android.hardware.security.keymint-V1-ndk_platform",
"android.hardware.security.secureclock-V1-ndk_platform",
"libcppbor_external",
"libcppcose_rkp",
+ "libkeymint",
"libkeymint_remote_prov_support",
+ "libkeymint_support",
"libkeymint_vts_test_utils",
],
test_suites: [
@@ -69,8 +69,6 @@
shared_libs: [
"libbinder_ndk",
"libcrypto",
- "libkeymint",
- "libkeymint_support",
],
static_libs: [
"android.hardware.security.keymint-V1-ndk_platform",
@@ -78,7 +76,9 @@
"libcppbor_external",
"libcppcose_rkp",
"libgmock_ndk",
+ "libkeymint",
"libkeymint_remote_prov_support",
+ "libkeymint_support",
],
}
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index b8699e9..ae2becd 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -141,11 +141,18 @@
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
+ // The returned key characteristics will include CREATION_DATETIME (checked below)
+ // in SecurityLevel::KEYSTORE; this will be stripped out in the CheckCharacteristics()
+ // call below, to match what getKeyCharacteristics() returns (which doesn't include
+ // any SecurityLevel::KEYSTORE characteristics).
+ CheckCharacteristics(attested_key_blob, attested_key_characteristics);
+
CheckedDeleteKey(&attested_key_blob);
CheckedDeleteKey(&attest_key.keyBlob);
hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+
// The client-specified CREATION_DATETIME should be in sw_enforced.
// Its presence will also trigger verify_attestation_record() to check that it
// is in the attestation extension with a matching value.
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 0eac033..44b8274 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -44,7 +44,9 @@
using ::testing::AssertionFailure;
using ::testing::AssertionResult;
using ::testing::AssertionSuccess;
+using ::testing::ElementsAreArray;
using ::testing::MatchesRegex;
+using ::testing::Not;
::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set) {
if (set.size() == 0)
@@ -140,6 +142,15 @@
return filtered;
}
+// Remove any SecurityLevel::KEYSTORE entries from a list of key characteristics.
+void strip_keystore_tags(vector<KeyCharacteristics>* characteristics) {
+ characteristics->erase(std::remove_if(characteristics->begin(), characteristics->end(),
+ [](const auto& entry) {
+ return entry.securityLevel == SecurityLevel::KEYSTORE;
+ }),
+ characteristics->end());
+}
+
string x509NameToStr(X509_NAME* name) {
char* s = X509_NAME_oneline(name, nullptr, 0);
string retval(s);
@@ -318,6 +329,65 @@
return GetReturnErrorCode(result);
}
+ErrorCode KeyMintAidlTestBase::GetCharacteristics(const vector<uint8_t>& key_blob,
+ const vector<uint8_t>& app_id,
+ const vector<uint8_t>& app_data,
+ vector<KeyCharacteristics>* key_characteristics) {
+ Status result =
+ keymint_->getKeyCharacteristics(key_blob, app_id, app_data, key_characteristics);
+ return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::GetCharacteristics(const vector<uint8_t>& key_blob,
+ vector<KeyCharacteristics>* key_characteristics) {
+ vector<uint8_t> empty_app_id, empty_app_data;
+ return GetCharacteristics(key_blob, empty_app_id, empty_app_data, key_characteristics);
+}
+
+void KeyMintAidlTestBase::CheckCharacteristics(
+ const vector<uint8_t>& key_blob,
+ const vector<KeyCharacteristics>& generate_characteristics) {
+ // Any key characteristics that were in SecurityLevel::KEYSTORE when returned from
+ // generateKey() should be excluded, as KeyMint will have no record of them.
+ // This applies to CREATION_DATETIME in particular.
+ vector<KeyCharacteristics> expected_characteristics(generate_characteristics);
+ strip_keystore_tags(&expected_characteristics);
+
+ vector<KeyCharacteristics> retrieved;
+ ASSERT_EQ(ErrorCode::OK, GetCharacteristics(key_blob, &retrieved));
+ EXPECT_EQ(expected_characteristics, retrieved);
+}
+
+void KeyMintAidlTestBase::CheckAppIdCharacteristics(
+ const vector<uint8_t>& key_blob, std::string_view app_id_string,
+ std::string_view app_data_string,
+ const vector<KeyCharacteristics>& generate_characteristics) {
+ // Exclude any SecurityLevel::KEYSTORE characteristics for comparisons.
+ vector<KeyCharacteristics> expected_characteristics(generate_characteristics);
+ strip_keystore_tags(&expected_characteristics);
+
+ vector<uint8_t> app_id(app_id_string.begin(), app_id_string.end());
+ vector<uint8_t> app_data(app_data_string.begin(), app_data_string.end());
+ vector<KeyCharacteristics> retrieved;
+ ASSERT_EQ(ErrorCode::OK, GetCharacteristics(key_blob, app_id, app_data, &retrieved));
+ EXPECT_EQ(expected_characteristics, retrieved);
+
+ // Check that key characteristics can't be retrieved if the app ID or app data is missing.
+ vector<uint8_t> empty;
+ vector<KeyCharacteristics> not_retrieved;
+ EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+ GetCharacteristics(key_blob, empty, app_data, ¬_retrieved));
+ EXPECT_EQ(not_retrieved.size(), 0);
+
+ EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+ GetCharacteristics(key_blob, app_id, empty, ¬_retrieved));
+ EXPECT_EQ(not_retrieved.size(), 0);
+
+ EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+ GetCharacteristics(key_blob, empty, empty, ¬_retrieved));
+ EXPECT_EQ(not_retrieved.size(), 0);
+}
+
ErrorCode KeyMintAidlTestBase::DeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
Status result = keymint_->deleteKey(*key_blob);
if (!keep_key_blob) {
@@ -1548,14 +1618,17 @@
EXPECT_EQ(extractedTag.size(), 32U);
// Compare with tag generated with kTestMacKey. Should only match in test mode
- auto testTag = cppcose::generateCoseMac0Mac(remote_prov::kTestMacKey, {} /* external_aad */,
- payload->value());
+ auto macFunction = [](const cppcose::bytevec& input) {
+ return cppcose::generateHmacSha256(remote_prov::kTestMacKey, input);
+ };
+ auto testTag =
+ cppcose::generateCoseMac0Mac(macFunction, {} /* external_aad */, payload->value());
ASSERT_TRUE(testTag) << "Tag calculation failed: " << testTag.message();
if (testMode) {
- EXPECT_EQ(*testTag, extractedTag);
+ EXPECT_THAT(*testTag, ElementsAreArray(extractedTag));
} else {
- EXPECT_NE(*testTag, extractedTag);
+ EXPECT_THAT(*testTag, Not(ElementsAreArray(extractedTag)));
}
if (payload_value != nullptr) {
*payload_value = payload->value();
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index d8f1bb3..c49b303 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -16,6 +16,8 @@
#pragma once
+#include <string_view>
+
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <binder/IServiceManager.h>
@@ -104,6 +106,18 @@
unwrapping_params, 0 /* password_sid */, 0 /* biometric_sid */);
}
+ ErrorCode GetCharacteristics(const vector<uint8_t>& key_blob, const vector<uint8_t>& app_id,
+ const vector<uint8_t>& app_data,
+ vector<KeyCharacteristics>* key_characteristics);
+ ErrorCode GetCharacteristics(const vector<uint8_t>& key_blob,
+ vector<KeyCharacteristics>* key_characteristics);
+
+ void CheckCharacteristics(const vector<uint8_t>& key_blob,
+ const vector<KeyCharacteristics>& generate_characteristics);
+ void CheckAppIdCharacteristics(const vector<uint8_t>& key_blob, std::string_view app_id_string,
+ std::string_view app_data_string,
+ const vector<KeyCharacteristics>& generate_characteristics);
+
ErrorCode DeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob = false);
ErrorCode DeleteKey(bool keep_key_blob = false);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 8b1eb30..5dcfcaa 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -560,6 +560,7 @@
EXPECT_GT(key_blob.size(), 0U);
CheckSymmetricParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -742,6 +743,7 @@
EXPECT_GT(key_blob.size(), 0U);
CheckSymmetricParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -788,6 +790,7 @@
EXPECT_GT(key_blob.size(), 0U);
CheckSymmetricParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -865,6 +868,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -911,6 +915,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -978,6 +983,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1108,6 +1114,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1176,6 +1183,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1211,6 +1219,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1266,6 +1275,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1362,6 +1372,7 @@
&key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1405,6 +1416,7 @@
&key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1452,6 +1464,7 @@
&key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1511,6 +1524,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1555,6 +1569,7 @@
&key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1594,6 +1609,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
@@ -1726,6 +1742,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
@@ -1761,6 +1778,7 @@
ASSERT_GT(key_blob.size(), 0U);
ASSERT_EQ(cert_chain_.size(), 0);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
@@ -1791,6 +1809,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
+ CheckCharacteristics(key_blob, key_characteristics);
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
@@ -2044,6 +2063,9 @@
.Authorization(TAG_APPLICATION_ID, "clientid")
.Authorization(TAG_APPLICATION_DATA, "appdata")
.SetDefaultValidity()));
+
+ CheckAppIdCharacteristics(key_blob_, "clientid", "appdata", key_characteristics_);
+
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
Begin(KeyPurpose::SIGN,
AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)));
@@ -2558,6 +2580,9 @@
.Authorization(TAG_APPLICATION_ID, "clientid")
.Authorization(TAG_APPLICATION_DATA, "appdata")
.SetDefaultValidity()));
+
+ CheckAppIdCharacteristics(key_blob_, "clientid", "appdata", key_characteristics_);
+
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
Begin(KeyPurpose::SIGN, AuthorizationSetBuilder().Digest(Digest::NONE)));
AbortIfNeeded();
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index a2071c2..a177317 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -340,6 +340,7 @@
cppbor::Array() // SignedMacAad
.add(challenge_)
.add(std::move(deviceInfoMap))
+ .add(keysToSignMac)
.encode());
ASSERT_TRUE(macKey) << macKey.message();
diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
index 2fbd29a..fcf2ee8 100644
--- a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
+++ b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
@@ -39,7 +39,7 @@
* 32-byte HMAC-SHA256 of the above values, computed as:
*
* HMAC(H,
- * ISecureClock.TIME_STAMP_MAC_LABEL || challenge || timestamp || securityLevel )
+ * ISecureClock.TIME_STAMP_MAC_LABEL || challenge || timestamp || 1 )
*
* where:
*
@@ -50,9 +50,7 @@
* ``||'' represents concatenation
*
* The representation of challenge and timestamp is as 64-bit unsigned integers in big-endian
- * order. SecurityLevel is represented as a 32-bit unsigned integer in big-endian order as
- * described in android.hardware.security.keymint.SecurityLevel. It represents the security
- * level of the secure clock environment.
+ * order. 1, above, is a 32-bit unsigned integer, also big-endian.
*/
byte[] mac;
}