Merge "KeyMint VTS: test getKeyCharacteristics()"
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_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/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 44b015f..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)
@@ -1616,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/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;
 }