Merge "audio: update setAudioPatch" into main
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index a10e0a6..18fc4b2 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -534,7 +534,8 @@
direction_configurations,
const std::vector<std::optional<AseDirectionRequirement>>& requirements,
std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
- valid_direction_configurations) {
+ valid_direction_configurations,
+ bool isExact) {
if (!direction_configurations.has_value()) return;
if (!valid_direction_configurations.has_value()) {
@@ -542,55 +543,93 @@
std::vector<std::optional<AseDirectionConfiguration>>();
}
- // Exact matching process
- // Need to respect the number of device
- for (int i = 0; i < requirements.size(); ++i) {
- auto requirement = requirements[i];
- auto direction_configuration = direction_configurations.value()[i];
- if (!direction_configuration.has_value()) {
- valid_direction_configurations = std::nullopt;
- return;
- }
- auto cfg = direction_configuration.value();
- if (!filterMatchedAseConfiguration(cfg.aseConfiguration,
- requirement.value().aseConfiguration)) {
- valid_direction_configurations = std::nullopt;
- return; // No way to match
- }
- // For exact match, we require this direction to have the same allocation.
- // If stereo, need stereo.
- // If mono, need mono (modified to the correct required allocation)
- auto req_allocation_bitmask = getLeAudioAseConfigurationAllocationBitmask(
- requirement.value().aseConfiguration);
- int req_channel_count = getCountFromBitmask(req_allocation_bitmask);
- int cfg_bitmask =
- getLeAudioAseConfigurationAllocationBitmask(cfg.aseConfiguration);
- int cfg_channel_count = getCountFromBitmask(cfg_bitmask);
- if (req_channel_count <= 1) {
- // MONO case, is a match if also mono, modify to the same allocation
- if (cfg_channel_count > 1) {
+ if (isExact) {
+ // Exact matching process
+ // Need to respect the number of device
+ for (int i = 0; i < requirements.size(); ++i) {
+ auto requirement = requirements[i];
+ auto direction_configuration = direction_configurations.value()[i];
+ if (!direction_configuration.has_value()) {
valid_direction_configurations = std::nullopt;
- return; // Not a match
+ return;
}
- // Modify the bitmask to be the same as the requirement
- for (auto& codec_cfg : cfg.aseConfiguration.codecConfiguration) {
- if (codec_cfg.getTag() ==
- CodecSpecificConfigurationLtv::Tag::audioChannelAllocation) {
- codec_cfg
- .get<CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
- .bitmask = req_allocation_bitmask;
- break;
+ auto cfg = direction_configuration.value();
+ if (!filterMatchedAseConfiguration(
+ cfg.aseConfiguration, requirement.value().aseConfiguration)) {
+ valid_direction_configurations = std::nullopt;
+ return; // No way to match
+ }
+ // For exact match, we require this direction to have the same allocation.
+ // If stereo, need stereo.
+ // If mono, need mono (modified to the correct required allocation)
+ auto req_allocation_bitmask = getLeAudioAseConfigurationAllocationBitmask(
+ requirement.value().aseConfiguration);
+ int req_channel_count = getCountFromBitmask(req_allocation_bitmask);
+ int cfg_bitmask =
+ getLeAudioAseConfigurationAllocationBitmask(cfg.aseConfiguration);
+ int cfg_channel_count = getCountFromBitmask(cfg_bitmask);
+ if (req_channel_count <= 1) {
+ // MONO case, is a match if also mono, modify to the same allocation
+ if (cfg_channel_count > 1) {
+ valid_direction_configurations = std::nullopt;
+ return; // Not a match
+ }
+ // Modify the bitmask to be the same as the requirement
+ for (auto& codec_cfg : cfg.aseConfiguration.codecConfiguration) {
+ if (codec_cfg.getTag() ==
+ CodecSpecificConfigurationLtv::Tag::audioChannelAllocation) {
+ codec_cfg
+ .get<CodecSpecificConfigurationLtv::Tag::
+ audioChannelAllocation>()
+ .bitmask = req_allocation_bitmask;
+ break;
+ }
+ }
+ } else {
+ // STEREO case, is a match if same allocation
+ if (req_allocation_bitmask != cfg_bitmask) {
+ valid_direction_configurations = std::nullopt;
+ return; // Not a match
}
}
- } else {
- // STEREO case, is a match if same allocation
- if (req_allocation_bitmask != cfg_bitmask) {
+ // Push to list if valid
+ valid_direction_configurations.value().push_back(cfg);
+ }
+ } else {
+ // Loose matching process
+ for (auto& requirement : requirements) {
+ if (!requirement.has_value()) continue;
+ auto req_allocation_bitmask = getLeAudioAseConfigurationAllocationBitmask(
+ requirement.value().aseConfiguration);
+ auto req_channel_count = getCountFromBitmask(req_allocation_bitmask);
+
+ auto temp = std::vector<AseDirectionConfiguration>();
+
+ for (auto direction_configuration : direction_configurations.value()) {
+ if (!direction_configuration.has_value()) continue;
+ if (!filterMatchedAseConfiguration(
+ direction_configuration.value().aseConfiguration,
+ requirement.value().aseConfiguration))
+ continue;
+ // Valid if match any requirement.
+ temp.push_back(direction_configuration.value());
+ }
+
+ // Get the best matching config based on channel allocation
+ auto total_cfg_channel_count = 0;
+ auto req_valid_configs = getValidConfigurationsFromAllocation(
+ req_allocation_bitmask, temp, isExact);
+ // Count and check required channel counts
+ for (auto& cfg : req_valid_configs) {
+ total_cfg_channel_count += getCountFromBitmask(
+ getLeAudioAseConfigurationAllocationBitmask(cfg.aseConfiguration));
+ valid_direction_configurations.value().push_back(cfg);
+ }
+ if (total_cfg_channel_count != req_channel_count) {
valid_direction_configurations = std::nullopt;
- return; // Not a match
+ return;
}
}
- // Push to list if valid
- valid_direction_configurations.value().push_back(cfg);
}
}
@@ -650,8 +689,8 @@
std::optional<LeAudioAseConfigurationSetting>
LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings(
IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
- const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
- requirement) {
+ const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement,
+ bool isExact) {
// Create a new LeAudioAseConfigurationSetting to return
// Make context the same as the requirement
LeAudioAseConfigurationSetting filtered_setting{
@@ -664,25 +703,27 @@
// is the number of device.
// The exact matching process is as follow:
- // 1. Setting direction has the same number of cfg (ignore when null require)
+ // 1. Setting direction has the same number of cfg (ignore when null
+ // require)
// 2. For each index, it's a 1-1 filter / mapping.
+ if (isExact) {
+ if (requirement.sinkAseRequirement.has_value() &&
+ requirement.sinkAseRequirement.value().size() !=
+ setting.sinkAseConfiguration.value().size()) {
+ return std::nullopt;
+ }
- if (requirement.sinkAseRequirement.has_value() &&
- requirement.sinkAseRequirement.value().size() !=
- setting.sinkAseConfiguration.value().size()) {
- return std::nullopt;
- }
-
- if (requirement.sourceAseRequirement.has_value() &&
- requirement.sourceAseRequirement.value().size() !=
- setting.sourceAseConfiguration.value().size()) {
- return std::nullopt;
+ if (requirement.sourceAseRequirement.has_value() &&
+ requirement.sourceAseRequirement.value().size() !=
+ setting.sourceAseConfiguration.value().size()) {
+ return std::nullopt;
+ }
}
if (requirement.sinkAseRequirement.has_value()) {
filterRequirementAseDirectionConfiguration(
setting.sinkAseConfiguration, requirement.sinkAseRequirement.value(),
- filtered_setting.sinkAseConfiguration);
+ filtered_setting.sinkAseConfiguration, isExact);
if (!filtered_setting.sinkAseConfiguration.has_value()) {
return std::nullopt;
}
@@ -692,7 +733,7 @@
filterRequirementAseDirectionConfiguration(
setting.sourceAseConfiguration,
requirement.sourceAseRequirement.value(),
- filtered_setting.sourceAseConfiguration);
+ filtered_setting.sourceAseConfiguration, isExact);
if (!filtered_setting.sourceAseConfiguration.has_value()) {
return std::nullopt;
}
@@ -706,9 +747,10 @@
std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>&
matched_ase_configuration_settings,
const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement,
- bool isMatchContext) {
+ bool isMatchContext, bool isExact) {
LOG(INFO) << __func__ << ": Trying to match for the requirement "
- << requirement.toString() << ", match context = " << isMatchContext;
+ << requirement.toString() << ", match context = " << isMatchContext
+ << ", match exact = " << isExact;
for (auto& setting : matched_ase_configuration_settings) {
// Try to match context in metadata.
if (isMatchContext) {
@@ -720,7 +762,8 @@
}
auto filtered_ase_configuration_setting =
- getRequirementMatchedAseConfigurationSettings(setting, requirement);
+ getRequirementMatchedAseConfigurationSettings(setting, requirement,
+ isExact);
if (filtered_ase_configuration_setting.has_value()) {
LOG(INFO) << __func__ << ": Result found: "
<< getSettingOutputString(
@@ -811,26 +854,30 @@
// Matching priority list:
// Preferred context - exact match with allocation
+ // Preferred context - loose match with allocation
// Any context - exact match with allocation
- auto matched_setting_with_context = matchWithRequirement(
- matched_ase_configuration_settings, requirement, true);
- if (matched_setting_with_context.has_value()) {
- result.push_back(matched_setting_with_context.value());
- } else {
- auto matched_setting = matchWithRequirement(
- matched_ase_configuration_settings, requirement, false);
- if (matched_setting.has_value()) {
- result.push_back(matched_setting.value());
- } else {
- // Cannot find a match for this requirement
- // Immediately return
- LOG(ERROR)
- << __func__
- << ": Cannot find any match for this requirement, exitting...";
- result.clear();
- *_aidl_return = result;
- return ndk::ScopedAStatus::ok();
+ // Any context - loose match with allocation
+ bool found = false;
+ for (bool match_context : {true, false}) {
+ for (bool match_exact : {true, false}) {
+ auto matched_setting =
+ matchWithRequirement(matched_ase_configuration_settings,
+ requirement, match_context, match_exact);
+ if (matched_setting.has_value()) {
+ result.push_back(matched_setting.value());
+ found = true;
+ break;
+ }
}
+ if (found) break;
+ }
+
+ if (!found) {
+ LOG(ERROR) << __func__
+ << ": Cannot find any match for this requirement, exitting...";
+ result.clear();
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
}
}
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
index 798f183..3a82b73 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -139,7 +139,8 @@
direction_configurations,
const std::vector<std::optional<AseDirectionRequirement>>& requirements,
std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
- valid_direction_configurations);
+ valid_direction_configurations,
+ bool isExact);
std::optional<LeAudioAseConfigurationSetting>
getCapabilitiesMatchedAseConfigurationSettings(
IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
@@ -149,7 +150,8 @@
getRequirementMatchedAseConfigurationSettings(
IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
- requirement);
+ requirement,
+ bool isExact);
bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos,
AseQosDirectionRequirement requirement_qos);
std::optional<LeAudioBroadcastConfigurationSetting>
@@ -173,7 +175,7 @@
matched_ase_configuration_settings,
const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
requirements,
- bool isMatchContext);
+ bool isMatchContext, bool isExact);
};
class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 4b762ca..935382e 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -312,7 +312,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.security.secretkeeper</name>
- <version>1</version>
+ <version>1-2</version>
<interface>
<name>ISecretkeeper</name>
<instance>default</instance>
@@ -653,6 +653,15 @@
</interface>
</hal>
<hal format="aidl">
+ <name>android.hardware.virtualization.capabilities</name>
+ <version>1</version>
+ <interface>
+ <name>IVmCapabilitiesService</name>
+ <instance>default</instance>
+ <instance>noop</instance>
+ </interface>
+ </hal>
+ <hal format="aidl">
<name>android.hardware.weaver</name>
<version>2</version>
<interface>
diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
index 083a9aa..b41da3f 100644
--- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
+++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
@@ -95,6 +95,18 @@
<< "Verified boot state must be \"UNVERIFIED\" aka \"orange\".";
}
+// Check that the attested Verified Boot key is 32 bytes of zeroes since the bootloader is unlocked.
+TEST_P(BootloaderStateTest, VerifiedBootKeyAllZeroes) {
+ // Gate this test to avoid waiver issues.
+ if (get_vsr_api_level() <= __ANDROID_API_V__) {
+ return;
+ }
+
+ std::vector<uint8_t> expectedVbKey(32, 0);
+ ASSERT_EQ(attestedVbKey_, expectedVbKey) << "Verified Boot key digest must be 32 bytes of "
+ "zeroes since the bootloader is unlocked.";
+}
+
// Following error codes from avb_slot_data() mean that slot data was loaded
// (even if verification failed).
static inline bool avb_slot_data_loaded(AvbSlotVerifyResult result) {
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 0ce6a15..09446ce 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1908,16 +1908,29 @@
}
}
+ if (get_vsr_api_level() > __ANDROID_API_V__) {
+ // The Verified Boot key field should be exactly 32 bytes since it
+ // contains the SHA-256 hash of the key on locked devices or 32 bytes
+ // of zeroes on unlocked devices. This wasn't checked for earlier
+ // versions of the KeyMint HAL, so only only be strict for VSR-16+.
+ EXPECT_EQ(verified_boot_key.size(), 32);
+ } else if (get_vsr_api_level() == __ANDROID_API_V__) {
+ // The Verified Boot key field should be:
+ // - Exactly 32 bytes on locked devices since it should contain
+ // the SHA-256 hash of the key, or
+ // - Up to 32 bytes of zeroes on unlocked devices (behaviour on
+ // unlocked devices isn't specified in the HAL interface
+ // specification).
+ // Thus, we can't check for strict equality in case unlocked devices
+ // report values with less than 32 bytes. This wasn't checked for
+ // earlier versions of the KeyMint HAL, so only check on VSR-15.
+ EXPECT_LE(verified_boot_key.size(), 32);
+ }
+
// Verified Boot key should be all zeroes if the boot state is "orange".
std::string empty_boot_key(32, '\0');
std::string verified_boot_key_str((const char*)verified_boot_key.data(),
verified_boot_key.size());
- if (get_vsr_api_level() >= __ANDROID_API_V__) {
- // The attestation should contain the SHA-256 hash of the verified boot
- // key. However, this was not checked for earlier versions of the KeyMint
- // HAL so only be strict for VSR-V and above.
- EXPECT_LE(verified_boot_key.size(), 32);
- }
EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
if (!strcmp(property_value, "green")) {
EXPECT_EQ(verified_boot_state, VerifiedBoot::VERIFIED);
diff --git a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
index 9f7322a..f7639bf 100644
--- a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
+++ b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
@@ -114,10 +114,22 @@
const auto& vbKey = rot->asArray()->get(pos++);
ASSERT_TRUE(vbKey);
ASSERT_TRUE(vbKey->asBstr());
- if (get_vsr_api_level() >= __ANDROID_API_V__) {
- // The attestation should contain the SHA-256 hash of the verified boot
- // key. However, this not was checked for earlier versions of the KeyMint
- // HAL so only be strict for VSR-V and above.
+ if (get_vsr_api_level() > __ANDROID_API_V__) {
+ // The Verified Boot key field should be exactly 32 bytes since it
+ // contains the SHA-256 hash of the key on locked devices or 32 bytes
+ // of zeroes on unlocked devices. This wasn't checked for earlier
+ // versions of the KeyMint HAL, so only only be strict for VSR-16+.
+ ASSERT_EQ(vbKey->asBstr()->value().size(), 32);
+ } else if (get_vsr_api_level() == __ANDROID_API_V__) {
+ // The Verified Boot key field should be:
+ // - Exactly 32 bytes on locked devices since it should contain
+ // the SHA-256 hash of the key, or
+ // - Up to 32 bytes of zeroes on unlocked devices (behaviour on
+ // unlocked devices isn't specified in the HAL interface
+ // specification).
+ // Thus, we can't check for strict equality in case unlocked devices
+ // report values with less than 32 bytes. This wasn't checked for
+ // earlier versions of the KeyMint HAL, so only check on VSR-15.
ASSERT_LE(vbKey->asBstr()->value().size(), 32);
}
diff --git a/security/secretkeeper/aidl/Android.bp b/security/secretkeeper/aidl/Android.bp
index d282621..f0b7894 100644
--- a/security/secretkeeper/aidl/Android.bp
+++ b/security/secretkeeper/aidl/Android.bp
@@ -25,7 +25,7 @@
"android.hardware.security.authgraph-V1",
],
stability: "vintf",
- frozen: true,
+ frozen: false,
backend: {
java: {
enabled: true,
@@ -88,6 +88,6 @@
rust_defaults {
name: "secretkeeper_use_latest_hal_aidl_rust",
rustlibs: [
- "android.hardware.security.secretkeeper-V1-rust",
+ "android.hardware.security.secretkeeper-V2-rust",
],
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index 8ce37cd..ed48480 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -38,6 +38,7 @@
byte[] processSecretManagementRequest(in byte[] request);
void deleteIds(in android.hardware.security.secretkeeper.SecretId[] ids);
void deleteAll();
+ android.hardware.security.secretkeeper.PublicKey getSecretkeeperIdentity();
const int ERROR_UNKNOWN_KEY_ID = 1;
const int ERROR_INTERNAL_ERROR = 2;
const int ERROR_REQUEST_MALFORMED = 3;
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/PublicKey.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/PublicKey.aidl
new file mode 100644
index 0000000..f690abf
--- /dev/null
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/PublicKey.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 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 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 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
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.secretkeeper;
+/* @hide */
+@VintfStability
+parcelable PublicKey {
+ byte[] keyMaterial;
+}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index b07dba8..91493a1 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -17,6 +17,7 @@
package android.hardware.security.secretkeeper;
import android.hardware.security.authgraph.IAuthGraphKeyExchange;
+import android.hardware.security.secretkeeper.PublicKey;
import android.hardware.security.secretkeeper.SecretId;
@VintfStability
@@ -101,4 +102,12 @@
* Delete data of all clients.
*/
void deleteAll();
+
+ /**
+ * Gets the public key of the secret keeper instance. This should be a CBOR-encoded
+ * COSE_Key, as a PubKeyEd25519 / PubKeyECDSA256 / PubKeyECDSA384, as defined in
+ * generateCertificateRequestV2.cddl. Clients must have a trusted way of ensuring
+ * this key is valid.
+ */
+ PublicKey getSecretkeeperIdentity();
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/PublicKey.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/PublicKey.aidl
new file mode 100644
index 0000000..ccc89b3
--- /dev/null
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/PublicKey.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.hardware.security.secretkeeper;
+
+/**
+ * Contents of a pubkey.
+ * @hide
+ */
+@VintfStability
+parcelable PublicKey {
+ /**
+ * CBOR-encoded COSE_Key
+ */
+ byte[] keyMaterial;
+}
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index be07a7b..c84afae 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -38,6 +38,7 @@
srcs: ["secretkeeper_test_client.rs"],
defaults: [
"rdroidtest.defaults",
+ "secretkeeper_use_latest_hal_aidl_rust",
],
test_suites: [
"general-tests",
@@ -45,7 +46,6 @@
],
test_config: "AndroidTest.xml",
rustlibs: [
- "android.hardware.security.secretkeeper-V1-rust",
"libauthgraph_boringssl",
"libauthgraph_core",
"libauthgraph_wire",
@@ -66,9 +66,10 @@
rust_binary {
name: "secretkeeper_cli",
srcs: ["secretkeeper_cli.rs"],
+ defaults: ["secretkeeper_use_latest_hal_aidl_rust"],
lints: "android",
- rlibs: [
- "android.hardware.security.secretkeeper-V1-rust",
+ prefer_rlib: true,
+ rustlibs: [
"libanyhow",
"libauthgraph_boringssl",
"libauthgraph_core",
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index 449a99a..b944865 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -16,6 +16,7 @@
use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::SecretId::SecretId;
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::PublicKey::PublicKey;
use authgraph_vts_test as ag_vts;
use authgraph_boringssl as boring;
use authgraph_core::key;
@@ -70,20 +71,32 @@
0x06, 0xAC, 0x36, 0x8B, 0x3C, 0x95, 0x50, 0x16, 0x67, 0x71, 0x65, 0x26, 0xEB, 0xD0, 0xC3, 0x98,
]);
-// Android expects the public key of Secretkeeper instance to be present in the Linux device tree.
+// Android expects the public key of Secretkeeper instance to be available either
+// a) by being present in the Linux device tree (prior to version 2 of the secretkeeper HAL), or
+// b) via the `getSecretKeeperIdentity` operation from v2 onwards.
// This allows clients to (cryptographically) verify that they are indeed talking to the real
// secretkeeper.
// Note that this is the identity of the `default` instance (and not `nonsecure`)!
-fn get_secretkeeper_identity() -> Option<CoseKey> {
- let path = Path::new(SECRETKEEPER_KEY_HOST_DT);
- if path.exists() {
- let key = fs::read(path).unwrap();
- let mut key = CoseKey::from_slice(&key).unwrap();
- key.canonicalize(CborOrdering::Lexicographic);
- Some(key)
+fn get_secretkeeper_identity(instance: &str) -> Option<CoseKey> {
+ let sk = get_connection(instance);
+ let key_material = if sk.getInterfaceVersion().expect("Error getting sk interface version") >= 2 {
+ let PublicKey { keyMaterial } = sk.getSecretkeeperIdentity().expect("Error calling getSecretkeeperIdentity");
+ Some(keyMaterial)
} else {
- None
- }
+ let path = Path::new(SECRETKEEPER_KEY_HOST_DT);
+ if path.exists() {
+ let key_material = fs::read(path).unwrap();
+ Some(key_material)
+ } else {
+ None
+ }
+ };
+
+ key_material.map(|km| {
+ let mut cose_key = CoseKey::from_slice(&km).expect("Error deserializing CoseKey from key material");
+ cose_key.canonicalize(CborOrdering::Lexicographic);
+ cose_key
+ })
}
fn get_instances() -> Vec<(String, String)> {
@@ -760,12 +773,12 @@
}
// This test checks that the identity of Secretkeeper (in context of AuthGraph key exchange) is
-// same as the one advertized in Linux device tree. This is only expected from `default` instance.
+// same as the one either a) advertized in Linux device tree or b) retrieved from SK itself
+// from (HAL v2 onwards). This is only expected from `default` instance.
#[rdroidtest(get_instances())]
-#[ignore_if(|p| p != "default")]
fn secretkeeper_check_identity(instance: String) {
- let sk_key = get_secretkeeper_identity()
- .expect("Failed to extract identity of default instance from device tree");
+ let sk_key = get_secretkeeper_identity(&instance)
+ .expect("Failed to extract identity of default instance");
// Create a session with this expected identity. This succeeds only if the identity used by
// Secretkeeper is sk_key.
let _ = SkClient::with_expected_sk_identity(&instance, sk_key).unwrap();
diff --git a/security/secretkeeper/default/Android.bp b/security/secretkeeper/default/Android.bp
index 799188f..134afc9 100644
--- a/security/secretkeeper/default/Android.bp
+++ b/security/secretkeeper/default/Android.bp
@@ -28,9 +28,9 @@
vendor_available: true,
defaults: [
"authgraph_use_latest_hal_aidl_rust",
+ "secretkeeper_use_latest_hal_aidl_rust",
],
rustlibs: [
- "android.hardware.security.secretkeeper-V1-rust",
"libauthgraph_boringssl",
"libauthgraph_core",
"libauthgraph_hal",
@@ -50,9 +50,9 @@
prefer_rlib: true,
defaults: [
"authgraph_use_latest_hal_aidl_rust",
+ "secretkeeper_use_latest_hal_aidl_rust",
],
rustlibs: [
- "android.hardware.security.secretkeeper-V1-rust",
"libandroid_logger",
"libbinder_rs",
"liblog_rust",
diff --git a/security/secretkeeper/default/secretkeeper.xml b/security/secretkeeper/default/secretkeeper.xml
index 40aebe0..699fff0 100644
--- a/security/secretkeeper/default/secretkeeper.xml
+++ b/security/secretkeeper/default/secretkeeper.xml
@@ -19,7 +19,7 @@
<hal format="aidl">
<name>android.hardware.security.secretkeeper</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>ISecretkeeper</name>
<instance>nonsecure</instance>
diff --git a/virtualization/capabilities_service/aidl/Android.bp b/virtualization/capabilities_service/aidl/Android.bp
new file mode 100644
index 0000000..b0bbbdd
--- /dev/null
+++ b/virtualization/capabilities_service/aidl/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2024 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.
+
+package {
+ default_team: "trendy_team_virtualization",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+ name: "android.hardware.virtualization.capabilities.capabilities_service",
+ vendor_available: true,
+ srcs: ["android/**/*.aidl"],
+ stability: "vintf",
+ backend: {
+ rust: {
+ enabled: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.virt",
+ ],
+ },
+ },
+ frozen: false,
+}
diff --git a/virtualization/capabilities_service/aidl/aidl_api/android.hardware.virtualization.capabilities.capabilities_service/current/android/hardware/virtualization/capabilities/IVmCapabilitiesService.aidl b/virtualization/capabilities_service/aidl/aidl_api/android.hardware.virtualization.capabilities.capabilities_service/current/android/hardware/virtualization/capabilities/IVmCapabilitiesService.aidl
new file mode 100644
index 0000000..68ff021
--- /dev/null
+++ b/virtualization/capabilities_service/aidl/aidl_api/android.hardware.virtualization.capabilities.capabilities_service/current/android/hardware/virtualization/capabilities/IVmCapabilitiesService.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 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 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 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
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.virtualization.capabilities;
+@VintfStability
+interface IVmCapabilitiesService {
+ void grantAccessToVendorTeeServices(in ParcelFileDescriptor vmFd, in String[] vendorTeeServices);
+}
diff --git a/virtualization/capabilities_service/aidl/android/hardware/virtualization/capabilities/IVmCapabilitiesService.aidl b/virtualization/capabilities_service/aidl/android/hardware/virtualization/capabilities/IVmCapabilitiesService.aidl
new file mode 100644
index 0000000..0d09ecb
--- /dev/null
+++ b/virtualization/capabilities_service/aidl/android/hardware/virtualization/capabilities/IVmCapabilitiesService.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.hardware.virtualization.capabilities;
+
+/**
+ * Encapsulates vendor-specific capabilities that can be granted to VMs.
+ */
+@VintfStability
+interface IVmCapabilitiesService {
+ /**
+ * Grant access for the VM represented by the given vm_fd to the given vendor-owned tee
+ * services. The names in |vendorTeeServices| must match the ones defined in the
+ * tee_service_contexts files.
+ * TODO(ioffe): link to the integration doc for custom smc filtering feature once
+ * it's ready.
+ */
+ void grantAccessToVendorTeeServices(
+ in ParcelFileDescriptor vmFd, in String[] vendorTeeServices);
+}