Merge "Update VTS tests for SatellitePvt and CorrelationVector" into sc-dev am: caa53dc3bb
Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/interfaces/+/14671676
Change-Id: I839106b25884e286cd90e849553f553566e6eb52
diff --git a/bluetooth/audio/2.1/default/Android.bp b/bluetooth/audio/2.1/default/Android.bp
index 5c30f79..3000223 100644
--- a/bluetooth/audio/2.1/default/Android.bp
+++ b/bluetooth/audio/2.1/default/Android.bp
@@ -19,6 +19,7 @@
"A2dpSoftwareAudioProvider.cpp",
"HearingAidAudioProvider.cpp",
"LeAudioAudioProvider.cpp",
+ "LeAudioOffloadAudioProvider.cpp",
],
header_libs: ["libhardware_headers"],
shared_libs: [
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
index e1b1ac6..b0d171a 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
@@ -41,8 +41,12 @@
BluetoothAudioProvidersFactory::hearing_aid_provider_instance_;
LeAudioOutputAudioProvider
BluetoothAudioProvidersFactory::leaudio_output_provider_instance_;
+LeAudioOffloadOutputAudioProvider
+ BluetoothAudioProvidersFactory::leaudio_offload_output_provider_instance_;
LeAudioInputAudioProvider
BluetoothAudioProvidersFactory::leaudio_input_provider_instance_;
+LeAudioOffloadInputAudioProvider
+ BluetoothAudioProvidersFactory::leaudio_offload_input_provider_instance_;
Return<void> BluetoothAudioProvidersFactory::openProvider(
const V2_0::SessionType sessionType, openProvider_cb _hidl_cb) {
@@ -90,9 +94,15 @@
case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
provider = &leaudio_output_provider_instance_;
break;
+ case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+ provider = &leaudio_offload_output_provider_instance_;
+ break;
case SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
provider = &leaudio_input_provider_instance_;
break;
+ case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
+ provider = &leaudio_offload_input_provider_instance_;
+ break;
default:
status = BluetoothAudioStatus::FAILURE;
}
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
index fd83694..f8f557e 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
@@ -23,6 +23,7 @@
#include "BluetoothAudioProvider.h"
#include "HearingAidAudioProvider.h"
#include "LeAudioAudioProvider.h"
+#include "LeAudioOffloadAudioProvider.h"
namespace android {
namespace hardware {
@@ -55,6 +56,8 @@
static HearingAidAudioProvider hearing_aid_provider_instance_;
static LeAudioOutputAudioProvider leaudio_output_provider_instance_;
static LeAudioInputAudioProvider leaudio_input_provider_instance_;
+ static LeAudioOffloadOutputAudioProvider leaudio_offload_output_provider_instance_;
+ static LeAudioOffloadInputAudioProvider leaudio_offload_input_provider_instance_;
};
extern "C" IBluetoothAudioProvidersFactory*
diff --git a/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.cpp
new file mode 100644
index 0000000..c11bdad
--- /dev/null
+++ b/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#define LOG_TAG "BTAudioProviderLeAudioOffload"
+
+#include "LeAudioOffloadAudioProvider.h"
+
+#include <android-base/logging.h>
+
+#include "BluetoothAudioSessionReport_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1;
+using ::android::hardware::Void;
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+
+using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider()
+ : LeAudioOffloadAudioProvider() {
+ session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
+}
+
+LeAudioOffloadInputAudioProvider::LeAudioOffloadInputAudioProvider()
+ : LeAudioOffloadAudioProvider() {
+ session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
+}
+
+LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider()
+ : BluetoothAudioProvider() {}
+
+bool LeAudioOffloadAudioProvider::isValid(const V2_0::SessionType& sessionType) {
+ LOG(ERROR) << __func__ << ", invalid session type for Offloaded Le Audio provider: "
+ << toString(sessionType);
+
+ return false;
+}
+
+bool LeAudioOffloadAudioProvider::isValid(const SessionType& sessionType) {
+ return (sessionType == session_type_);
+}
+
+Return<void> LeAudioOffloadAudioProvider::startSession_2_1(
+ const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
+ /**
+ * Initialize the audio platform if audioConfiguration is supported.
+ * Save the IBluetoothAudioPort interface, so that it can be used
+ * later to send stream control commands to the HAL client, based on
+ * interaction with Audio framework.
+ */
+ if (audioConfig.getDiscriminator() !=
+ AudioConfiguration::hidl_discriminator::leAudioCodecConfig) {
+ LOG(WARNING) << __func__
+ << " - Invalid Audio Configuration=" << toString(audioConfig);
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ }
+
+ if (!android::bluetooth::audio::IsOffloadLeAudioConfigurationValid(session_type_,
+ audioConfig.leAudioCodecConfig())) {
+ LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration="
+ << toString(audioConfig.leAudioCodecConfig());
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ }
+
+ return BluetoothAudioProvider::startSession_2_1(hostIf, audioConfig,
+ _hidl_cb);
+}
+
+Return<void> LeAudioOffloadAudioProvider::onSessionReady(startSession_cb _hidl_cb) {
+ BluetoothAudioSessionReport_2_1::OnSessionStarted(session_type_, stack_iface_,
+ nullptr, audio_config_);
+ _hidl_cb(BluetoothAudioStatus::SUCCESS, DataMQ::Descriptor());
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.h
new file mode 100644
index 0000000..564e9a3
--- /dev/null
+++ b/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#pragma once
+
+#include <android/hardware/bluetooth/audio/2.1/types.h>
+
+#include "BluetoothAudioProvider.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
+ public:
+ LeAudioOffloadAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+ bool isValid(const V2_0::SessionType& sessionType) override;
+
+ Return<void> startSession_2_1(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ const AudioConfiguration& audioConfig,
+ startSession_cb _hidl_cb) override;
+
+ private:
+ Return<void> onSessionReady(startSession_cb _hidl_cb) override;
+};
+
+class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
+ public:
+ LeAudioOffloadOutputAudioProvider();
+};
+
+class LeAudioOffloadInputAudioProvider : public LeAudioOffloadAudioProvider {
+ public:
+ LeAudioOffloadInputAudioProvider();
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
index 9d91196..3228a09 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
@@ -110,20 +110,29 @@
SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
session_type_2_1_ ==
SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
- bool is_offload_session =
+ bool is_offload_a2dp_session =
(session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
+ bool is_offload_le_audio_session =
+ (session_type_2_1_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type_2_1_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
auto audio_config_discriminator = audio_config.getDiscriminator();
bool is_software_audio_config =
(is_software_session &&
audio_config_discriminator ==
::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
hidl_discriminator::pcmConfig);
- bool is_offload_audio_config =
- (is_offload_session &&
+ bool is_a2dp_offload_audio_config =
+ (is_offload_a2dp_session &&
audio_config_discriminator ==
::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
hidl_discriminator::codecConfig);
- if (!is_software_audio_config && !is_offload_audio_config) {
+ bool is_le_audio_offload_audio_config =
+ (is_offload_le_audio_session &&
+ audio_config_discriminator ==
+ ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
+ hidl_discriminator::leAudioCodecConfig);
+ if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
+ !is_le_audio_offload_audio_config) {
return false;
}
audio_config_2_1_ = audio_config;
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp
index 8b0b0f7..c90ce6d 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp
@@ -122,6 +122,21 @@
return false;
}
+bool IsOffloadLeAudioConfigurationValid(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type,
+ const ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration&) {
+
+ if (session_type != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ return false;
+ }
+
+ //TODO: perform checks on le_audio_codec_config once we know supported parameters
+
+ return true;
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h
index 746d9c0..a52636c 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h
@@ -41,6 +41,11 @@
const ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration&
codec_config);
+bool IsOffloadLeAudioConfigurationValid(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type,
+ const ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration&
+ le_audio_codec_config);
} // namespace audio
} // namespace bluetooth
} // namespace android
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/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 31fa1ae..da55347 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -75,7 +75,6 @@
vintf_compatibility_matrix {
name: "framework_compatibility_matrix.current.xml",
- enabled: false,
stem: "compatibility_matrix.current.xml",
srcs: [
"compatibility_matrix.current.xml",
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index 4cefb55..9e715bf 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -102,6 +102,7 @@
framework_compatibility_matrix.4.xml \
framework_compatibility_matrix.5.xml \
framework_compatibility_matrix.6.xml \
+ framework_compatibility_matrix.current.xml \
framework_compatibility_matrix.device.xml \
my_framework_matrix_deps += \
diff --git a/compatibility_matrices/build/vintf_compatibility_matrix.go b/compatibility_matrices/build/vintf_compatibility_matrix.go
index f1bd0ae..c72cbde 100644
--- a/compatibility_matrices/build/vintf_compatibility_matrix.go
+++ b/compatibility_matrices/build/vintf_compatibility_matrix.go
@@ -153,7 +153,7 @@
if k, ok := m.(*configs.KernelConfigRule); ok {
inputPaths = append(inputPaths, k.OutputPath())
} else {
- ctx.PropertyErrorf("kernel_config",
+ ctx.PropertyErrorf("kernel_configs",
"module %q is not a kernel_config", ctx.OtherModuleName(m))
}
})
diff --git a/current.txt b/current.txt
index 3102972..30c43ec 100644
--- a/current.txt
+++ b/current.txt
@@ -891,4 +891,7 @@
2123482b69f3b531c88023aa2a007110e130efbf4ed68ac9ce0bc55d5e82bc8b android.hardware.wifi.supplicant@1.4::ISupplicantStaNetworkCallback
0821f516e4d428bc15251969f7e19411c94d8f2ccbd99e1fc8168d8e49e38b0f android.hardware.wifi.supplicant@1.4::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/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/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 4ff4574..58e02b3 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -831,14 +831,24 @@
/**
* DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attested key generation/import
* operations. It indicates that attestation using a device-unique key is requested, rather
- * than a batch key. When a device-unique key is used, only the attestation certificate is
- * returned; no additional chained certificates are provided. It's up to the caller to
- * recognize the device-unique signing key. Only SecurityLevel::STRONGBOX IKeyMintDevices may
- * support device-unique attestations. SecurityLevel::TRUSTED_ENVIRONMENT IKeyMintDevices must
- * return ErrorCode::INVALID_ARGUMENT if they receive DEVICE_UNIQUE_ATTESTATION.
+ * than a batch key. When a device-unique key is used, the returned chain should contain two
+ * certificates:
+ * * The attestation certificate, containing the attestation extension, as described in
+ KeyCreationResult.aidl.
+ * * A self-signed root certificate, signed by the device-unique key.
+ * No additional chained certificates are provided. Only SecurityLevel::STRONGBOX
+ * IKeyMintDevices may support device-unique attestations. SecurityLevel::TRUSTED_ENVIRONMENT
+ * IKeyMintDevices must return ErrorCode::INVALID_ARGUMENT if they receive
+ * DEVICE_UNIQUE_ATTESTATION.
* SecurityLevel::STRONGBOX IKeyMintDevices need not support DEVICE_UNIQUE_ATTESTATION, and
* return ErrorCode::CANNOT_ATTEST_IDS if they do not support it.
*
+ * The caller needs to obtain the device-unique keys out-of-band and compare them against the
+ * key used to sign the self-signed root certificate.
+ * To ease this process, the IKeyMintDevice implementation should include, both in the subject
+ * and issuer fields of the self-signed root, the unique identifier of the device. Using the
+ * unique identifier will make it straightforward for the caller to link a device to its key.
+ *
* IKeyMintDevice implementations that support device-unique attestation MUST add the
* DEVICE_UNIQUE_ATTESTATION tag to device-unique attestations.
*/
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/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index b0f056a..732d9eb 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -42,8 +42,11 @@
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) << "Key size missing";
+ // The device-unique attestation chain should contain exactly two certificates:
+ // * The leaf with the attestation extension.
+ // * A self-signed root, signed using the device-unique key.
+ ASSERT_EQ(cert_chain_.size(), 2);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
- ASSERT_GT(cert_chain_.size(), 0);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index a9a67bc..44b8274 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -142,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);
@@ -320,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) {
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index d8f1bb3..4d31fa4 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -16,6 +16,9 @@
#pragma once
+#include <functional>
+#include <string_view>
+
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <binder/IServiceManager.h>
@@ -104,6 +107,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);
@@ -192,50 +207,58 @@
template <typename TagType>
std::tuple<KeyData /* aesKey */, KeyData /* hmacKey */, KeyData /* rsaKey */,
KeyData /* ecdsaKey */>
- CreateTestKeys(TagType tagToTest, ErrorCode expectedReturn) {
+ CreateTestKeys(
+ TagType tagToTest, ErrorCode expectedReturn,
+ std::function<void(AuthorizationSetBuilder*)> tagModifier =
+ [](AuthorizationSetBuilder*) {}) {
/* AES */
KeyData aesKeyData;
- ErrorCode errorCode = GenerateKey(AuthorizationSetBuilder()
- .AesEncryptionKey(128)
- .Authorization(tagToTest)
- .BlockMode(BlockMode::ECB)
- .Padding(PaddingMode::NONE)
- .Authorization(TAG_NO_AUTH_REQUIRED),
- &aesKeyData.blob, &aesKeyData.characteristics);
+ AuthorizationSetBuilder aesBuilder = AuthorizationSetBuilder()
+ .AesEncryptionKey(128)
+ .Authorization(tagToTest)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED);
+ tagModifier(&aesBuilder);
+ ErrorCode errorCode =
+ GenerateKey(aesBuilder, &aesKeyData.blob, &aesKeyData.characteristics);
EXPECT_EQ(expectedReturn, errorCode);
/* HMAC */
KeyData hmacKeyData;
- errorCode = GenerateKey(AuthorizationSetBuilder()
- .HmacKey(128)
- .Authorization(tagToTest)
- .Digest(Digest::SHA_2_256)
- .Authorization(TAG_MIN_MAC_LENGTH, 128)
- .Authorization(TAG_NO_AUTH_REQUIRED),
- &hmacKeyData.blob, &hmacKeyData.characteristics);
+ AuthorizationSetBuilder hmacBuilder = AuthorizationSetBuilder()
+ .HmacKey(128)
+ .Authorization(tagToTest)
+ .Digest(Digest::SHA_2_256)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Authorization(TAG_NO_AUTH_REQUIRED);
+ tagModifier(&hmacBuilder);
+ errorCode = GenerateKey(hmacBuilder, &hmacKeyData.blob, &hmacKeyData.characteristics);
EXPECT_EQ(expectedReturn, errorCode);
/* RSA */
KeyData rsaKeyData;
- errorCode = GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
- .Authorization(tagToTest)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- &rsaKeyData.blob, &rsaKeyData.characteristics);
+ AuthorizationSetBuilder rsaBuilder = AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Authorization(tagToTest)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity();
+ tagModifier(&rsaBuilder);
+ errorCode = GenerateKey(rsaBuilder, &rsaKeyData.blob, &rsaKeyData.characteristics);
EXPECT_EQ(expectedReturn, errorCode);
/* ECDSA */
KeyData ecdsaKeyData;
- errorCode = GenerateKey(AuthorizationSetBuilder()
- .EcdsaSigningKey(256)
- .Authorization(tagToTest)
- .Digest(Digest::SHA_2_256)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- &ecdsaKeyData.blob, &ecdsaKeyData.characteristics);
+ AuthorizationSetBuilder ecdsaBuilder = AuthorizationSetBuilder()
+ .EcdsaSigningKey(256)
+ .Authorization(tagToTest)
+ .Digest(Digest::SHA_2_256)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity();
+ tagModifier(&ecdsaBuilder);
+ errorCode = GenerateKey(ecdsaBuilder, &ecdsaKeyData.blob, &ecdsaKeyData.characteristics);
EXPECT_EQ(expectedReturn, errorCode);
return {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData};
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 8b1eb30..295be1a 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();
@@ -6330,6 +6355,11 @@
auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK);
+ for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) {
+ ASSERT_GT(keyData.blob.size(), 0U);
+ AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics);
+ EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params;
+ }
CheckedDeleteKey(&aesKeyData.blob);
CheckedDeleteKey(&hmacKeyData.blob);
CheckedDeleteKey(&rsaKeyData.blob);
@@ -6337,7 +6367,30 @@
}
/*
- * EarlyBootKeyTest.UsetEarlyBootKeyFailure
+ * EarlyBootKeyTest.CreateAttestedEarlyBootKey
+ *
+ * Verifies that creating an early boot key with attestation succeeds.
+ */
+TEST_P(EarlyBootKeyTest, CreateAttestedEarlyBootKey) {
+ auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] = CreateTestKeys(
+ TAG_EARLY_BOOT_ONLY, ErrorCode::OK, [](AuthorizationSetBuilder* builder) {
+ builder->AttestationChallenge("challenge");
+ builder->AttestationApplicationId("app_id");
+ });
+
+ for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) {
+ ASSERT_GT(keyData.blob.size(), 0U);
+ AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics);
+ EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params;
+ }
+ CheckedDeleteKey(&aesKeyData.blob);
+ CheckedDeleteKey(&hmacKeyData.blob);
+ CheckedDeleteKey(&rsaKeyData.blob);
+ CheckedDeleteKey(&ecdsaKeyData.blob);
+}
+
+/*
+ * EarlyBootKeyTest.UseEarlyBootKeyFailure
*
* Verifies that using early boot keys at a later stage fails.
*/
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;
}