Merge "audio: Add a missing include to ModuleConfig.cpp" into main
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 0ab990a..89d186c 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -297,6 +297,7 @@
"android/hardware/audio/effect/PresetReverb.aidl",
"android/hardware/audio/effect/Processing.aidl",
"android/hardware/audio/effect/Range.aidl",
+ "android/hardware/audio/effect/Spatializer.aidl",
"android/hardware/audio/effect/State.aidl",
"android/hardware/audio/effect/VendorExtension.aidl",
"android/hardware/audio/effect/Virtualizer.aidl",
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
index 0422bd9..7313b57 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -60,6 +60,7 @@
android.hardware.audio.effect.Visualizer.Id visualizerTag;
android.hardware.audio.effect.Volume.Id volumeTag;
android.hardware.audio.effect.Parameter.Tag commonTag;
+ android.hardware.audio.effect.Spatializer.Id spatializerTag;
}
@VintfStability
parcelable Common {
@@ -91,5 +92,6 @@
android.hardware.audio.effect.Virtualizer virtualizer;
android.hardware.audio.effect.Visualizer visualizer;
android.hardware.audio.effect.Volume volume;
+ android.hardware.audio.effect.Spatializer spatializer;
}
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
index 93edc5e..40ee6b5 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
@@ -50,6 +50,7 @@
android.hardware.audio.effect.Range.VirtualizerRange[] virtualizer;
android.hardware.audio.effect.Range.VisualizerRange[] visualizer;
android.hardware.audio.effect.Range.VolumeRange[] volume;
+ android.hardware.audio.effect.Range.SpatializerRange[] spatializer;
@VintfStability
parcelable AcousticEchoCancelerRange {
android.hardware.audio.effect.AcousticEchoCanceler min;
@@ -111,6 +112,11 @@
android.hardware.audio.effect.PresetReverb max;
}
@VintfStability
+ parcelable SpatializerRange {
+ android.hardware.audio.effect.Spatializer min;
+ android.hardware.audio.effect.Spatializer max;
+ }
+ @VintfStability
parcelable VendorExtensionRange {
android.hardware.audio.effect.VendorExtension min;
android.hardware.audio.effect.VendorExtension max;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl
new file mode 100644
index 0000000..9f97de0
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 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.audio.effect;
+@VintfStability
+union Spatializer {
+ android.hardware.audio.effect.VendorExtension vendor;
+ android.media.audio.common.Spatialization.Level spatializationLevel;
+ android.media.audio.common.HeadTracking.Mode headTrackingMode;
+ android.media.audio.common.AudioChannelLayout[] supportedChannelLayout;
+ android.media.audio.common.Spatialization.Mode spatializationMode;
+ float[6] headToStage;
+ const int HEAD_TO_STAGE_VEC_SIZE = 6;
+ @VintfStability
+ union Id {
+ android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+ android.hardware.audio.effect.Spatializer.Tag commonTag;
+ }
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
index 0954055..6ec7226 100644
--- a/audio/aidl/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -28,6 +28,7 @@
import android.hardware.audio.effect.LoudnessEnhancer;
import android.hardware.audio.effect.NoiseSuppression;
import android.hardware.audio.effect.PresetReverb;
+import android.hardware.audio.effect.Spatializer;
import android.hardware.audio.effect.VendorExtension;
import android.hardware.audio.effect.Virtualizer;
import android.hardware.audio.effect.Visualizer;
@@ -103,6 +104,11 @@
* directly.
*/
Parameter.Tag commonTag;
+
+ /**
+ * Parameter tag defined for Spatializer parameters.
+ */
+ Spatializer.Id spatializerTag;
}
/**
@@ -189,6 +195,7 @@
Virtualizer virtualizer;
Visualizer visualizer;
Volume volume;
+ Spatializer spatializer;
}
Specific specific;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Range.aidl b/audio/aidl/android/hardware/audio/effect/Range.aidl
index 567320a..e5acb68 100644
--- a/audio/aidl/android/hardware/audio/effect/Range.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Range.aidl
@@ -28,6 +28,7 @@
import android.hardware.audio.effect.LoudnessEnhancer;
import android.hardware.audio.effect.NoiseSuppression;
import android.hardware.audio.effect.PresetReverb;
+import android.hardware.audio.effect.Spatializer;
import android.hardware.audio.effect.VendorExtension;
import android.hardware.audio.effect.Virtualizer;
import android.hardware.audio.effect.Visualizer;
@@ -169,6 +170,12 @@
}
@VintfStability
+ parcelable SpatializerRange {
+ Spatializer min;
+ Spatializer max;
+ }
+
+ @VintfStability
parcelable VendorExtensionRange {
VendorExtension min;
VendorExtension max;
@@ -217,4 +224,5 @@
VirtualizerRange[] virtualizer;
VisualizerRange[] visualizer;
VolumeRange[] volume;
+ SpatializerRange[] spatializer;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Spatializer.aidl b/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
new file mode 100644
index 0000000..4edb2e8
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 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.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+import android.media.audio.common.AudioChannelLayout;
+import android.media.audio.common.HeadTracking;
+import android.media.audio.common.Spatialization;
+
+/**
+ * Union representing parameters for audio spatialization effects.
+ *
+ * Sound spatialization simulates sounds around the listener as if they were emanating from virtual
+ * positions based on the original recording.
+ * For more details, refer to the documentation:
+ * https://developer.android.com/reference/android/media/Spatializer.
+ *
+ * android.hardware.audio.effect.Spatializer specifies parameters for the implementation of audio
+ * spatialization effects.
+ *
+ * A Spatializer implementation must report its supported parameter ranges using Capability.Range.
+ * spatializer.
+ */
+@VintfStability
+union Spatializer {
+ /**
+ * Parameter tag to identify the parameters for getParameter().
+ */
+ @VintfStability
+ union Id {
+ VendorExtension vendorExtensionTag;
+ Spatializer.Tag commonTag;
+ }
+
+ /**
+ * Vendor extension implementation for additional parameters.
+ */
+ VendorExtension vendor;
+
+ /**
+ * Level of spatialization.
+ */
+ Spatialization.Level spatializationLevel;
+
+ /**
+ * Head tracking mode for spatialization.
+ */
+ HeadTracking.Mode headTrackingMode;
+
+ /**
+ * List of supported input channel layouts.
+ */
+ AudioChannelLayout[] supportedChannelLayout;
+
+ /**
+ * Spatialization mode, Binaural or Transaural for example.
+ */
+ Spatialization.Mode spatializationMode;
+
+ /**
+ * Vector representing of the head-to-stage pose with six floats: first three are a translation
+ * vector, and the last three are a rotation vector.
+ */
+ const int HEAD_TO_STAGE_VEC_SIZE = 6;
+ float[HEAD_TO_STAGE_VEC_SIZE] headToStage;
+}
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 59ca92a..ef312d5 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -175,7 +175,7 @@
}
constexpr int32_t frameCountFromDurationUs(long durationUs, int32_t sampleRateHz) {
- return (durationUs * sampleRateHz) / 1000000LL;
+ return (static_cast<long long>(durationUs) * sampleRateHz) / 1000000LL;
}
constexpr int32_t frameCountFromDurationMs(int32_t durationMs, int32_t sampleRateHz) {
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index d09552b..254eb46 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -302,8 +302,9 @@
// 2. The canonical r_submix configuration only lists 'STEREO' and '48000',
// however the framework attempts to open streams for other sample rates
// as well. The legacy r_submix implementation allowed that, but libaudiohal@aidl
-// will not find a mix port to use. Because of that, list all channel
-// masks and sample rates that the legacy implementation allowed.
+// will not find a mix port to use. Because of that, list all sample rates that
+// the legacy implementation allowed (note that mono was not allowed, the framework
+// is expected to upmix mono tracks into stereo if needed).
// 3. The legacy implementation had a hard limit on the number of routes (10),
// and this is checked indirectly by AudioPlaybackCaptureTest#testPlaybackCaptureDoS
// CTS test. Instead of hardcoding the number of routes, we can use
@@ -331,9 +332,8 @@
std::unique_ptr<Configuration> getRSubmixConfiguration() {
static const Configuration configuration = []() {
Configuration c;
- const std::vector<AudioProfile> standardPcmAudioProfiles{
- createProfile(PcmType::INT_16_BIT,
- {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
+ const std::vector<AudioProfile> remoteSubmixPcmAudioProfiles{
+ createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO},
{8000, 11025, 16000, 32000, 44100, 48000})};
// Device ports
@@ -343,25 +343,25 @@
createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0,
AudioDeviceDescription::CONNECTION_VIRTUAL));
c.ports.push_back(rsubmixOutDevice);
- c.connectedProfiles[rsubmixOutDevice.id] = standardPcmAudioProfiles;
+ c.connectedProfiles[rsubmixOutDevice.id] = remoteSubmixPcmAudioProfiles;
AudioPort rsubmixInDevice =
createPort(c.nextPortId++, "Remote Submix In", 0, true,
createDeviceExt(AudioDeviceType::IN_SUBMIX, 0,
AudioDeviceDescription::CONNECTION_VIRTUAL));
c.ports.push_back(rsubmixInDevice);
- c.connectedProfiles[rsubmixInDevice.id] = standardPcmAudioProfiles;
+ c.connectedProfiles[rsubmixInDevice.id] = remoteSubmixPcmAudioProfiles;
// Mix ports
AudioPort rsubmixOutMix =
createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(20, 10));
- rsubmixOutMix.profiles = standardPcmAudioProfiles;
+ rsubmixOutMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixOutMix);
AudioPort rsubmixInMix =
createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(20, 10));
- rsubmixInMix.profiles = standardPcmAudioProfiles;
+ rsubmixInMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixInMix);
c.routes.push_back(createRoute({rsubmixOutMix}, rsubmixOutDevice));
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index 38281b9..fc61dcb 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -131,6 +131,8 @@
LOG(DEBUG) << __func__ << ": shutting down MonoPipe sink";
sink->shutdown(true);
+ // The client already considers this stream as closed, release the output end.
+ route->closeStream(mIsInput);
} else {
LOG(DEBUG) << __func__ << ": stream already closed.";
ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
diff --git a/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.cpp b/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.cpp
index 96110db..e882160 100644
--- a/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.cpp
+++ b/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.cpp
@@ -18,9 +18,9 @@
namespace android::hardware::automotive::can::V1_0::implementation::fuzzer {
-constexpr CanController::InterfaceType kInterfaceType[] = {CanController::InterfaceType::VIRTUAL,
- CanController::InterfaceType::SOCKETCAN,
- CanController::InterfaceType::SLCAN};
+constexpr CanController::InterfaceType kInterfaceType[] = {
+ CanController::InterfaceType::VIRTUAL, CanController::InterfaceType::SOCKETCAN,
+ CanController::InterfaceType::SLCAN, CanController::InterfaceType::INDEXED};
constexpr FilterFlag kFilterFlag[] = {FilterFlag::DONT_CARE, FilterFlag::SET, FilterFlag::NOT_SET};
constexpr size_t kInterfaceTypeLength = std::size(kInterfaceType);
constexpr size_t kFilterFlagLength = std::size(kFilterFlag);
@@ -28,8 +28,8 @@
constexpr size_t kMaxPayloadBytes = 64;
constexpr size_t kMaxFilters = 20;
constexpr size_t kMaxSerialNumber = 1000;
-constexpr size_t kMaxBuses = 10;
-constexpr size_t kMaxRepeat = 5;
+constexpr size_t kMaxBuses = 100;
+constexpr size_t kMaxRepeat = 100;
Bus CanFuzzer::makeBus() {
ICanController::BusConfig config = {};
@@ -56,9 +56,13 @@
}
void CanFuzzer::invokeUpInterface() {
- const CanController::InterfaceType iftype =
- kInterfaceType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
- 0, kInterfaceTypeLength - 1)];
+ CanController::InterfaceType controller;
+ if (mFuzzedDataProvider->ConsumeBool()) {
+ controller = (CanController::InterfaceType)mFuzzedDataProvider->ConsumeIntegral<uint8_t>();
+ } else {
+ controller = kInterfaceType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
+ 0, kInterfaceTypeLength - 1)];
+ }
std::string configName;
if (const bool shouldInvokeValidBus = mFuzzedDataProvider->ConsumeBool();
@@ -73,7 +77,7 @@
ICanController::BusConfig config = {.name = configName};
- if (iftype == CanController::InterfaceType::SOCKETCAN) {
+ if (controller == CanController::InterfaceType::SOCKETCAN) {
CanController::BusConfig::InterfaceId::Socketcan socketcan = {};
if (const bool shouldPassSerialSocket = mFuzzedDataProvider->ConsumeBool();
shouldPassSerialSocket) {
@@ -83,7 +87,7 @@
socketcan.ifname(ifname);
}
config.interfaceId.socketcan(socketcan);
- } else if (iftype == CanController::InterfaceType::SLCAN) {
+ } else if (controller == CanController::InterfaceType::SLCAN) {
CanController::BusConfig::InterfaceId::Slcan slcan = {};
if (const bool shouldPassSerialSlcan = mFuzzedDataProvider->ConsumeBool();
shouldPassSerialSlcan) {
@@ -93,8 +97,12 @@
slcan.ttyname(ifname);
}
config.interfaceId.slcan(slcan);
- } else if (iftype == CanController::InterfaceType::VIRTUAL) {
+ } else if (controller == CanController::InterfaceType::VIRTUAL) {
config.interfaceId.virtualif({ifname});
+ } else if (controller == CanController::InterfaceType::INDEXED) {
+ CanController::BusConfig::InterfaceId::Indexed indexed;
+ indexed.index = mFuzzedDataProvider->ConsumeIntegral<uint8_t>();
+ config.interfaceId.indexed(indexed);
}
const size_t numInvocations =
@@ -108,8 +116,13 @@
hidl_string configName;
if (const bool shouldInvokeValidBus = mFuzzedDataProvider->ConsumeBool();
(shouldInvokeValidBus) && (mBusNames.size() > 0)) {
- const size_t busNameIndex =
- mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, mBusNames.size() - 1);
+ size_t busNameIndex;
+ if (mBusNames.size() == 1) {
+ busNameIndex = 0;
+ } else {
+ busNameIndex =
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, mBusNames.size() - 1);
+ }
configName = mBusNames[busNameIndex];
} else {
configName = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
@@ -122,12 +135,6 @@
}
}
-void CanFuzzer::invokeController() {
- getSupportedInterfaceTypes();
- invokeUpInterface();
- invokeDownInterface();
-}
-
void CanFuzzer::invokeBus() {
const size_t numBuses = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(1, kMaxBuses);
for (size_t i = 0; i < numBuses; ++i) {
@@ -152,12 +159,22 @@
for (uint32_t k = 0; k < numFilters; ++k) {
filterVector[k].id = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
filterVector[k].mask = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
- filterVector[k].rtr =
- kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
- 0, kFilterFlagLength - 1)];
- filterVector[k].extendedFormat =
- kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
- 0, kFilterFlagLength - 1)];
+ if (mFuzzedDataProvider->ConsumeBool()) {
+ filterVector[k].rtr =
+ (FilterFlag)mFuzzedDataProvider->ConsumeIntegral<uint8_t>();
+ } else {
+ filterVector[k].rtr =
+ kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
+ 0, kFilterFlagLength - 1)];
+ }
+ if (mFuzzedDataProvider->ConsumeBool()) {
+ filterVector[k].extendedFormat =
+ (FilterFlag)mFuzzedDataProvider->ConsumeIntegral<uint8_t>();
+ } else {
+ filterVector[k].extendedFormat =
+ kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
+ 0, kFilterFlagLength - 1)];
+ }
filterVector[k].exclude = mFuzzedDataProvider->ConsumeBool();
}
auto listener = listeningBus.listen(filterVector);
@@ -175,8 +192,16 @@
void CanFuzzer::process(const uint8_t* data, size_t size) {
mFuzzedDataProvider = new FuzzedDataProvider(data, size);
- invokeController();
- invokeBus();
+ while (mFuzzedDataProvider->remaining_bytes()) {
+ auto CanFuzzerFunction =
+ mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
+ [&]() { getSupportedInterfaceTypes(); },
+ [&]() { invokeUpInterface(); },
+ [&]() { invokeDownInterface(); },
+ [&]() { invokeBus(); },
+ });
+ CanFuzzerFunction();
+ }
}
bool CanFuzzer::init() {
diff --git a/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.h b/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.h
index 930cddd..3211bd0 100644
--- a/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.h
+++ b/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.h
@@ -116,7 +116,6 @@
hidl_vec<hidl_string> getBusNames();
void getSupportedInterfaceTypes();
void invokeBus();
- void invokeController();
void invokeUpInterface();
void invokeDownInterface();
FuzzedDataProvider* mFuzzedDataProvider = nullptr;
diff --git a/bluetooth/aidl/default/BluetoothHci.cpp b/bluetooth/aidl/default/BluetoothHci.cpp
index 9862e9e..a247cb0 100644
--- a/bluetooth/aidl/default/BluetoothHci.cpp
+++ b/bluetooth/aidl/default/BluetoothHci.cpp
@@ -320,6 +320,7 @@
{
std::lock_guard<std::mutex> guard(mStateMutex);
mState = HalState::READY;
+ mH4 = nullptr;
}
return ndk::ScopedAStatus::ok();
}
@@ -346,13 +347,16 @@
ndk::ScopedAStatus BluetoothHci::send(PacketType type,
const std::vector<uint8_t>& v) {
- if (mH4 == nullptr) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
if (v.empty()) {
ALOGE("Packet is empty, no data was found to be sent");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
+
+ std::lock_guard<std::mutex> guard(mStateMutex);
+ if (mH4 == nullptr) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+
mH4->Send(type, v);
return ndk::ScopedAStatus::ok();
}
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
index c962974..88e4b75 100644
--- a/camera/device/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -786,9 +786,8 @@
outputBuffer.bufferId = buffer.bufferId;
outputBuffer.status = BufferStatus::ERROR;
if (buffer.acquireFence >= 0) {
- native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
- handle->data[0] = buffer.acquireFence;
- outputBuffer.releaseFence = android::makeToAidl(handle);
+ outputBuffer.releaseFence.fds.resize(1);
+ outputBuffer.releaseFence.fds.at(0).set(buffer.acquireFence);
}
} else {
offlineBuffers.push_back(buffer);
@@ -1769,9 +1768,8 @@
result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
result.outputBuffers[i].status = BufferStatus::ERROR;
if (req->buffers[i].acquireFence >= 0) {
- native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
- handle->data[0] = req->buffers[i].acquireFence;
- result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+ result.outputBuffers[i].releaseFence.fds.resize(1);
+ result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
}
}
@@ -1815,18 +1813,16 @@
if (req->buffers[i].fenceTimeout) {
result.outputBuffers[i].status = BufferStatus::ERROR;
if (req->buffers[i].acquireFence >= 0) {
- native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
- handle->data[0] = req->buffers[i].acquireFence;
- result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+ result.outputBuffers[i].releaseFence.fds.resize(1);
+ result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
}
notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
} else {
result.outputBuffers[i].status = BufferStatus::OK;
// TODO: refactor
if (req->buffers[i].acquireFence >= 0) {
- native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
- handle->data[0] = req->buffers[i].acquireFence;
- result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+ result.outputBuffers[i].releaseFence.fds.resize(1);
+ result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
}
}
}
diff --git a/cas/aidl/default/service.cpp b/cas/aidl/default/service.cpp
index bed2f01..076c7bb 100644
--- a/cas/aidl/default/service.cpp
+++ b/cas/aidl/default/service.cpp
@@ -31,6 +31,7 @@
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(8);
+ ABinderProcess_startThreadPool();
// Setup hwbinder service
std::shared_ptr<MediaCasService> service = ::ndk::SharedRefBase::make<MediaCasService>();
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index d356cf3..c2ffb84 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -106,9 +106,15 @@
framework_compatibility_matrix.6.xml \
framework_compatibility_matrix.7.xml \
framework_compatibility_matrix.8.xml \
- framework_compatibility_matrix.9.xml \
framework_compatibility_matrix.device.xml \
+# Only allow the use of the unreleased compatibility matrix when we can use unfrozen
+# interfaces (in the `next` release configuration).
+ifeq ($(RELEASE_AIDL_USE_UNFROZEN),true)
+my_system_matrix_deps += \
+ framework_compatibility_matrix.9.xml
+endif
+
my_framework_matrix_deps += \
$(my_system_matrix_deps)
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
index 99dcdbb..9057788 100644
--- a/compatibility_matrices/compatibility_matrix.8.xml
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -52,7 +52,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.authsecret</name>
<version>1</version>
<interface>
@@ -123,7 +123,7 @@
<instance>virtual</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.biometrics.fingerprint</name>
<version>3</version>
<interface>
@@ -314,7 +314,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.security.keymint</name>
<version>1-3</version>
<interface>
@@ -323,7 +323,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.security.keymint</name>
<version>1-3</version>
<interface>
@@ -532,7 +532,7 @@
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.security.secureclock</name>
<version>1</version>
<interface>
@@ -540,7 +540,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.security.sharedsecret</name>
<version>1</version>
<interface>
@@ -692,7 +692,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.uwb</name>
<version>1</version>
<interface>
diff --git a/keymaster/4.0/support/fuzzer/Android.bp b/keymaster/4.0/support/fuzzer/Android.bp
index 8bc681a..f61d10f 100644
--- a/keymaster/4.0/support/fuzzer/Android.bp
+++ b/keymaster/4.0/support/fuzzer/Android.bp
@@ -39,9 +39,17 @@
],
fuzz_config: {
cc: [
- "android-media-fuzzing-reports@google.com",
+ "android-hardware-security@google.com",
],
- componentid: 533764,
+ componentid: 1084733,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libkeymaster4support",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/security/authgraph/aidl/vts/functional/lib.rs b/security/authgraph/aidl/vts/functional/lib.rs
index 7b9b2b9..da3fa1c 100644
--- a/security/authgraph/aidl/vts/functional/lib.rs
+++ b/security/authgraph/aidl/vts/functional/lib.rs
@@ -24,22 +24,19 @@
PlainPubKey::PlainPubKey, PubKey::PubKey, SessionIdSignature::SessionIdSignature,
};
use authgraph_boringssl as boring;
-use authgraph_core::keyexchange as ke;
-use authgraph_core::{arc, key, traits};
-use authgraph_nonsecure::StdClock;
+use authgraph_core::{error::Error as AgError, keyexchange as ke};
use coset::CborSerializable;
pub mod sink;
pub mod source;
-/// Return a collection of AuthGraph trait implementations suitable for testing.
-pub fn test_impls() -> traits::TraitImpl {
- // Note that the local implementation is using a clock with a potentially different epoch than
- // the implementation under test.
- boring::trait_impls(
+/// Return an AuthGraphParticipant suitable for testing.
+pub fn test_ag_participant() -> Result<ke::AuthGraphParticipant, AgError> {
+ Ok(ke::AuthGraphParticipant::new(
+ boring::crypto_trait_impls(),
Box::<boring::test_device::AgDevice>::default(),
- Some(Box::new(StdClock::default())),
- )
+ ke::MAX_OPENED_SESSIONS,
+ )?)
}
fn build_plain_pub_key(pub_key: &Option<Vec<u8>>) -> PubKey {
@@ -56,14 +53,6 @@
}
}
-fn verification_key_from_identity(impls: &traits::TraitImpl, identity: &[u8]) -> key::EcVerifyKey {
- let identity = key::Identity::from_slice(identity).expect("invalid identity CBOR");
- impls
- .device
- .process_peer_cert_chain(&identity.cert_chain, &*impls.ecdsa)
- .expect("failed to extract signing key")
-}
-
fn vec_to_identity(data: &[u8]) -> Identity {
Identity {
identity: data.to_vec(),
@@ -75,26 +64,3 @@
signature: data.to_vec(),
}
}
-
-/// Decrypt a pair of AES-256 keys encrypted with the AuthGraph PBK.
-pub fn decipher_aes_keys(imp: &traits::TraitImpl, arc: &[Vec<u8>; 2]) -> [key::AesKey; 2] {
- [
- decipher_aes_key(imp, &arc[0]),
- decipher_aes_key(imp, &arc[1]),
- ]
-}
-
-/// Decrypt an AES-256 key encrypted with the AuthGraph PBK.
-pub fn decipher_aes_key(imp: &traits::TraitImpl, arc: &[u8]) -> key::AesKey {
- let pbk = imp.device.get_per_boot_key().expect("no PBK available");
- let arc::ArcContent {
- payload,
- protected_headers: _,
- unprotected_headers: _,
- } = arc::decipher_arc(&pbk, arc, &*imp.aes_gcm).expect("failed to decrypt arc");
- assert_eq!(payload.0.len(), 32);
- let mut key = key::AesKey([0; 32]);
- key.0.copy_from_slice(&payload.0);
- assert_ne!(key.0, [0; 32], "agreed AES-256 key should be non-zero");
- key
-}
diff --git a/security/authgraph/aidl/vts/functional/role_test.rs b/security/authgraph/aidl/vts/functional/role_test.rs
index e95361a..71a2fae 100644
--- a/security/authgraph/aidl/vts/functional/role_test.rs
+++ b/security/authgraph/aidl/vts/functional/role_test.rs
@@ -48,31 +48,31 @@
#[test]
fn test_nonsecure_source_mainline() {
- let mut impls = vts::test_impls();
- vts::source::test_mainline(&mut impls, require_nonsecure!());
+ let mut sink = vts::test_ag_participant().expect("failed to create a local sink");
+ vts::source::test_mainline(&mut sink, require_nonsecure!());
}
#[test]
fn test_nonsecure_source_corrupt_sig() {
- let mut impls = vts::test_impls();
- vts::source::test_corrupt_sig(&mut impls, require_nonsecure!());
+ let mut sink = vts::test_ag_participant().expect("failed to create a local sink");
+ vts::source::test_corrupt_sig(&mut sink, require_nonsecure!());
}
#[test]
fn test_nonsecure_source_corrupt_keys() {
- let mut impls = vts::test_impls();
- vts::source::test_corrupt_key(&mut impls, require_nonsecure!());
+ let mut sink = vts::test_ag_participant().expect("failed to create a local sink");
+ vts::source::test_corrupt_key(&mut sink, require_nonsecure!());
}
#[test]
fn test_nonsecure_sink_mainline() {
- let mut impls = vts::test_impls();
- vts::sink::test_mainline(&mut impls, require_nonsecure!());
+ let mut source = vts::test_ag_participant().expect("failed to create a local source");
+ vts::sink::test_mainline(&mut source, require_nonsecure!());
}
#[test]
fn test_nonsecure_sink_corrupt_sig() {
- let mut impls = vts::test_impls();
- vts::sink::test_corrupt_sig(&mut impls, require_nonsecure!());
+ let mut source = vts::test_ag_participant().expect("failed to create a local source");
+ vts::sink::test_corrupt_sig(&mut source, require_nonsecure!());
}
#[test]
fn test_nonsecure_sink_corrupt_keys() {
- let mut impls = vts::test_impls();
- vts::sink::test_corrupt_keys(&mut impls, require_nonsecure!());
+ let mut source = vts::test_ag_participant().expect("failed to create a local source");
+ vts::sink::test_corrupt_keys(&mut source, require_nonsecure!());
}
diff --git a/security/authgraph/aidl/vts/functional/sink.rs b/security/authgraph/aidl/vts/functional/sink.rs
index 5c81593..bb357b8 100644
--- a/security/authgraph/aidl/vts/functional/sink.rs
+++ b/security/authgraph/aidl/vts/functional/sink.rs
@@ -16,23 +16,28 @@
//! VTS tests for sinks
use super::*;
-use authgraph_core::traits;
+use authgraph_core::{key, keyexchange as ke};
/// Run AuthGraph tests against the provided sink, using a local test source implementation.
-pub fn test(impls: &mut traits::TraitImpl, sink: binder::Strong<dyn IAuthGraphKeyExchange>) {
- test_mainline(impls, sink.clone());
- test_corrupt_sig(impls, sink.clone());
- test_corrupt_keys(impls, sink);
+pub fn test(
+ local_source: &mut ke::AuthGraphParticipant,
+ sink: binder::Strong<dyn IAuthGraphKeyExchange>,
+) {
+ test_mainline(local_source, sink.clone());
+ test_corrupt_sig(local_source, sink.clone());
+ test_corrupt_keys(local_source, sink);
}
/// Perform mainline AuthGraph key exchange with the provided sink and local implementation.
/// Return the agreed AES keys in plaintext.
pub fn test_mainline(
- impls: &mut traits::TraitImpl,
+ local_source: &mut ke::AuthGraphParticipant,
sink: binder::Strong<dyn IAuthGraphKeyExchange>,
) -> [key::AesKey; 2] {
// Step 1: create an ephemeral ECDH key at the (local) source.
- let source_init_info = ke::create(impls).expect("failed to create() with local impl");
+ let source_init_info = local_source
+ .create()
+ .expect("failed to create() with local impl");
// Step 2: pass the source's ECDH public key and other session info to the (remote) sink.
let init_result = sink
@@ -50,40 +55,43 @@
assert!(!sink_info.sessionId.is_empty());
// The AuthGraph core library will verify the session ID signature, but do it here too.
- let sink_verification_key =
- verification_key_from_identity(&impls, &sink_init_info.identity.identity);
- ke::verify_signature_on_session_id(
- &sink_verification_key,
- &sink_info.sessionId,
- &sink_info.signature.signature,
- &*impls.ecdsa,
- )
- .expect("failed verification of signed session ID");
+ let sink_verification_key = local_source
+ .peer_verification_key_from_identity(&sink_init_info.identity.identity)
+ .expect("failed to get peer verification from identity");
+ local_source
+ .verify_signature_on_session_id(
+ &sink_verification_key,
+ &sink_info.sessionId,
+ &sink_info.signature.signature,
+ )
+ .expect("failed verification of signed session ID");
// Step 3: pass the sink's ECDH public key and other session info to the (local) source, so it
// can calculate the same pair of symmetric keys.
- let source_info = ke::finish(
- impls,
- &sink_pub_key.plainPubKey,
- &sink_init_info.identity.identity,
- &sink_info.signature.signature,
- &sink_init_info.nonce,
- sink_init_info.version,
- source_init_info.ke_key,
- )
- .expect("failed to finish() with local impl");
+ let source_info = local_source
+ .finish(
+ &sink_pub_key.plainPubKey,
+ &sink_init_info.identity.identity,
+ &sink_info.signature.signature,
+ &sink_init_info.nonce,
+ sink_init_info.version,
+ source_init_info.ke_key,
+ )
+ .expect("failed to finish() with local impl");
assert!(!source_info.session_id.is_empty());
// The AuthGraph core library will verify the session ID signature, but do it here too.
- let source_verification_key =
- verification_key_from_identity(&impls, &source_init_info.identity);
- ke::verify_signature_on_session_id(
- &source_verification_key,
- &source_info.session_id,
- &source_info.session_id_signature,
- &*impls.ecdsa,
- )
- .expect("failed verification of signed session ID");
+ let source_verification_key = key::Identity::from_slice(&source_init_info.identity)
+ .expect("invalid identity CBOR")
+ .cert_chain
+ .root_key;
+ local_source
+ .verify_signature_on_session_id(
+ &source_verification_key,
+ &source_info.session_id,
+ &source_info.session_id_signature,
+ )
+ .expect("failed verification of signed session ID");
// Both ends should agree on the session ID.
assert_eq!(source_info.session_id, sink_info.sessionId);
@@ -96,19 +104,28 @@
&sink_info.sharedKeys,
)
.expect("failed to authenticationComplete() with remote sink");
-
// Decrypt and return the session keys.
- decipher_aes_keys(&impls, &source_info.shared_keys)
+ let decrypted_shared_keys = local_source
+ .decipher_shared_keys_from_arcs(&source_info.shared_keys)
+ .expect("failed to decrypt shared key arcs")
+ .try_into();
+ let decrypted_shared_keys_array = match decrypted_shared_keys {
+ Ok(array) => array,
+ Err(_) => panic!("wrong number of decrypted shared key arcs"),
+ };
+ decrypted_shared_keys_array
}
/// Perform mainline AuthGraph key exchange with the provided sink, but provide an invalid
/// session ID signature.
pub fn test_corrupt_sig(
- impls: &mut traits::TraitImpl,
+ local_source: &mut ke::AuthGraphParticipant,
sink: binder::Strong<dyn IAuthGraphKeyExchange>,
) {
// Step 1: create an ephemeral ECDH key at the (local) source.
- let source_init_info = ke::create(impls).expect("failed to create() with local impl");
+ let source_init_info = local_source
+ .create()
+ .expect("failed to create() with local impl");
// Step 2: pass the source's ECDH public key and other session info to the (remote) sink.
let init_result = sink
@@ -127,16 +144,16 @@
// Step 3: pass the sink's ECDH public key and other session info to the (local) source, so it
// can calculate the same pair of symmetric keys.
- let source_info = ke::finish(
- impls,
- &sink_pub_key.plainPubKey,
- &sink_init_info.identity.identity,
- &sink_info.signature.signature,
- &sink_init_info.nonce,
- sink_init_info.version,
- source_init_info.ke_key,
- )
- .expect("failed to finish() with local impl");
+ let source_info = local_source
+ .finish(
+ &sink_pub_key.plainPubKey,
+ &sink_init_info.identity.identity,
+ &sink_info.signature.signature,
+ &sink_init_info.nonce,
+ sink_init_info.version,
+ source_init_info.ke_key,
+ )
+ .expect("failed to finish() with local impl");
assert!(!source_info.session_id.is_empty());
// Build a corrupted version of the (local) source's session ID signature.
@@ -158,11 +175,13 @@
/// Perform mainline AuthGraph key exchange with the provided sink, but provide an invalid
/// Arc for the sink's key.
pub fn test_corrupt_keys(
- impls: &mut traits::TraitImpl,
+ local_source: &mut ke::AuthGraphParticipant,
sink: binder::Strong<dyn IAuthGraphKeyExchange>,
) {
// Step 1: create an ephemeral ECDH key at the (local) source.
- let source_init_info = ke::create(impls).expect("failed to create() with local impl");
+ let source_init_info = local_source
+ .create()
+ .expect("failed to create() with local impl");
// Step 2: pass the source's ECDH public key and other session info to the (remote) sink.
let init_result = sink
@@ -181,16 +200,16 @@
// Step 3: pass the sink's ECDH public key and other session info to the (local) source, so it
// can calculate the same pair of symmetric keys.
- let source_info = ke::finish(
- impls,
- &sink_pub_key.plainPubKey,
- &sink_init_info.identity.identity,
- &sink_info.signature.signature,
- &sink_init_info.nonce,
- sink_init_info.version,
- source_init_info.ke_key,
- )
- .expect("failed to finish() with local impl");
+ let source_info = local_source
+ .finish(
+ &sink_pub_key.plainPubKey,
+ &sink_init_info.identity.identity,
+ &sink_info.signature.signature,
+ &sink_init_info.nonce,
+ sink_init_info.version,
+ source_init_info.ke_key,
+ )
+ .expect("failed to finish() with local impl");
assert!(!source_info.session_id.is_empty());
// Deliberately corrupt the sink's shared key Arcs before returning them
diff --git a/security/authgraph/aidl/vts/functional/source.rs b/security/authgraph/aidl/vts/functional/source.rs
index 9aaaaee..4178a99 100644
--- a/security/authgraph/aidl/vts/functional/source.rs
+++ b/security/authgraph/aidl/vts/functional/source.rs
@@ -16,19 +16,22 @@
//! VTS tests for sources
use super::*;
-use authgraph_core::traits;
+use authgraph_core::{key, keyexchange as ke};
/// Run AuthGraph tests against the provided source, using a local test sink implementation.
-pub fn test(impls: &mut traits::TraitImpl, source: binder::Strong<dyn IAuthGraphKeyExchange>) {
- test_mainline(impls, source.clone());
- test_corrupt_sig(impls, source.clone());
- test_corrupt_key(impls, source);
+pub fn test(
+ local_sink: &mut ke::AuthGraphParticipant,
+ source: binder::Strong<dyn IAuthGraphKeyExchange>,
+) {
+ test_mainline(local_sink, source.clone());
+ test_corrupt_sig(local_sink, source.clone());
+ test_corrupt_key(local_sink, source);
}
/// Perform mainline AuthGraph key exchange with the provided source.
/// Return the agreed AES keys in plaintext.
pub fn test_mainline(
- impls: &mut traits::TraitImpl,
+ local_sink: &mut ke::AuthGraphParticipant,
source: binder::Strong<dyn IAuthGraphKeyExchange>,
) -> [key::AesKey; 2] {
// Step 1: create an ephemeral ECDH key at the (remote) source.
@@ -40,14 +43,14 @@
let source_pub_key = extract_plain_pub_key(&source_init_info.key.pubKey);
// Step 2: pass the source's ECDH public key and other session info to the (local) sink.
- let init_result = ke::init(
- impls,
- &source_pub_key.plainPubKey,
- &source_init_info.identity.identity,
- &source_init_info.nonce,
- source_init_info.version,
- )
- .expect("failed to init() with local impl");
+ let init_result = local_sink
+ .init(
+ &source_pub_key.plainPubKey,
+ &source_init_info.identity.identity,
+ &source_init_info.nonce,
+ source_init_info.version,
+ )
+ .expect("failed to init() with local impl");
let sink_init_info = init_result.session_init_info;
let sink_pub_key = sink_init_info
.ke_key
@@ -58,14 +61,17 @@
assert!(!sink_info.session_id.is_empty());
// The AuthGraph core library will verify the session ID signature, but do it here too.
- let sink_verification_key = verification_key_from_identity(&impls, &sink_init_info.identity);
- ke::verify_signature_on_session_id(
- &sink_verification_key,
- &sink_info.session_id,
- &sink_info.session_id_signature,
- &*impls.ecdsa,
- )
- .expect("failed verification of signed session ID");
+ let sink_verification_key = key::Identity::from_slice(&sink_init_info.identity)
+ .expect("invalid identity CBOR")
+ .cert_chain
+ .root_key;
+ local_sink
+ .verify_signature_on_session_id(
+ &sink_verification_key,
+ &sink_info.session_id,
+ &sink_info.session_id_signature,
+ )
+ .expect("failed verification of signed session ID");
// Step 3: pass the sink's ECDH public key and other session info to the (remote) source, so it
// can calculate the same pair of symmetric keys.
@@ -86,36 +92,41 @@
assert!(!source_info.sessionId.is_empty());
// The AuthGraph core library will verify the session ID signature, but do it here too.
- let source_verification_key =
- verification_key_from_identity(&impls, &source_init_info.identity.identity);
- ke::verify_signature_on_session_id(
- &source_verification_key,
- &source_info.sessionId,
- &source_info.signature.signature,
- &*impls.ecdsa,
- )
- .expect("failed verification of signed session ID");
+ let source_verification_key = local_sink
+ .peer_verification_key_from_identity(&source_init_info.identity.identity)
+ .expect("failed to get peer verification from identity");
+ local_sink
+ .verify_signature_on_session_id(
+ &source_verification_key,
+ &source_info.sessionId,
+ &source_info.signature.signature,
+ )
+ .expect("failed verification of signed session ID");
// Both ends should agree on the session ID.
assert_eq!(source_info.sessionId, sink_info.session_id);
// Step 4: pass the (remote) source's session ID signature back to the sink, so it can check it
// and update the symmetric keys so they're marked as authentication complete.
- let sink_arcs = ke::authentication_complete(
- impls,
- &source_info.signature.signature,
- sink_info.shared_keys,
- )
- .expect("failed to authenticationComplete() with local sink");
-
+ let sink_arcs = local_sink
+ .authentication_complete(&source_info.signature.signature, sink_info.shared_keys)
+ .expect("failed to authenticationComplete() with local sink");
// Decrypt and return the session keys.
- decipher_aes_keys(&impls, &sink_arcs)
+ let decrypted_shared_keys = local_sink
+ .decipher_shared_keys_from_arcs(&sink_arcs)
+ .expect("failed to decrypt shared key arcs")
+ .try_into();
+ let decrypted_shared_keys_array = match decrypted_shared_keys {
+ Ok(array) => array,
+ Err(_) => panic!("wrong number of decrypted shared key arcs"),
+ };
+ decrypted_shared_keys_array
}
/// Perform mainline AuthGraph key exchange with the provided source, but provide an invalid session
/// ID signature.
pub fn test_corrupt_sig(
- impls: &mut traits::TraitImpl,
+ local_sink: &mut ke::AuthGraphParticipant,
source: binder::Strong<dyn IAuthGraphKeyExchange>,
) {
// Step 1: create an ephemeral ECDH key at the (remote) source.
@@ -127,14 +138,14 @@
let source_pub_key = extract_plain_pub_key(&source_init_info.key.pubKey);
// Step 2: pass the source's ECDH public key and other session info to the (local) sink.
- let init_result = ke::init(
- impls,
- &source_pub_key.plainPubKey,
- &source_init_info.identity.identity,
- &source_init_info.nonce,
- source_init_info.version,
- )
- .expect("failed to init() with local impl");
+ let init_result = local_sink
+ .init(
+ &source_pub_key.plainPubKey,
+ &source_init_info.identity.identity,
+ &source_init_info.nonce,
+ source_init_info.version,
+ )
+ .expect("failed to init() with local impl");
let sink_init_info = init_result.session_init_info;
let sink_pub_key = sink_init_info
.ke_key
@@ -172,7 +183,7 @@
/// Perform mainline AuthGraph key exchange with the provided source, but give it back
/// a corrupted key.
pub fn test_corrupt_key(
- impls: &mut traits::TraitImpl,
+ local_sink: &mut ke::AuthGraphParticipant,
source: binder::Strong<dyn IAuthGraphKeyExchange>,
) {
// Step 1: create an ephemeral ECDH key at the (remote) source.
@@ -184,14 +195,14 @@
let source_pub_key = extract_plain_pub_key(&source_init_info.key.pubKey);
// Step 2: pass the source's ECDH public key and other session info to the (local) sink.
- let init_result = ke::init(
- impls,
- &source_pub_key.plainPubKey,
- &source_init_info.identity.identity,
- &source_init_info.nonce,
- source_init_info.version,
- )
- .expect("failed to init() with local impl");
+ let init_result = local_sink
+ .init(
+ &source_pub_key.plainPubKey,
+ &source_init_info.identity.identity,
+ &source_init_info.nonce,
+ source_init_info.version,
+ )
+ .expect("failed to init() with local impl");
let sink_init_info = init_result.session_init_info;
let sink_pub_key = sink_init_info
.ke_key
@@ -202,14 +213,17 @@
assert!(!sink_info.session_id.is_empty());
// The AuthGraph core library will verify the session ID signature, but do it here too.
- let sink_verification_key = verification_key_from_identity(&impls, &sink_init_info.identity);
- ke::verify_signature_on_session_id(
- &sink_verification_key,
- &sink_info.session_id,
- &sink_info.session_id_signature,
- &*impls.ecdsa,
- )
- .expect("failed verification of signed session ID");
+ let sink_verification_key = key::Identity::from_slice(&sink_init_info.identity)
+ .expect("invalid identity CBOR")
+ .cert_chain
+ .root_key;
+ local_sink
+ .verify_signature_on_session_id(
+ &sink_verification_key,
+ &sink_info.session_id,
+ &sink_info.session_id_signature,
+ )
+ .expect("failed verification of signed session ID");
// Deliberately corrupt the source's encrypted key.
let mut corrupt_key = source_init_info.key.clone();
diff --git a/security/authgraph/default/src/fuzzer.rs b/security/authgraph/default/src/fuzzer.rs
index 6a9cfdd..d401777 100644
--- a/security/authgraph/default/src/fuzzer.rs
+++ b/security/authgraph/default/src/fuzzer.rs
@@ -25,7 +25,7 @@
use std::sync::{Arc, Mutex};
fuzz_target!(|data: &[u8]| {
- let local_ta = LocalTa::new();
+ let local_ta = LocalTa::new().expect("Failed to create an AuthGraph local TA.");
let service = AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
fuzz_service(&mut service.as_binder(), data);
});
diff --git a/security/authgraph/default/src/lib.rs b/security/authgraph/default/src/lib.rs
index 4cd0cb7..43d037c 100644
--- a/security/authgraph/default/src/lib.rs
+++ b/security/authgraph/default/src/lib.rs
@@ -18,7 +18,9 @@
use authgraph_boringssl as boring;
use authgraph_core::{
+ error,
key::MillisecondsSinceEpoch,
+ keyexchange,
ta::{AuthGraphTa, Role},
traits,
};
@@ -57,16 +59,17 @@
impl LocalTa {
/// Create a new instance.
- pub fn new() -> Self {
- Self {
+ pub fn new() -> Result<Self, error::Error> {
+ Ok(Self {
ta: Arc::new(Mutex::new(AuthGraphTa::new(
- boring::trait_impls(
+ keyexchange::AuthGraphParticipant::new(
+ boring::crypto_trait_impls(),
Box::<boring::test_device::AgDevice>::default(),
- Some(Box::new(StdClock::default())),
- ),
+ keyexchange::MAX_OPENED_SESSIONS,
+ )?,
Role::Both,
))),
- }
+ })
}
}
diff --git a/security/authgraph/default/src/main.rs b/security/authgraph/default/src/main.rs
index 873eb4e..81f2dd6 100644
--- a/security/authgraph/default/src/main.rs
+++ b/security/authgraph/default/src/main.rs
@@ -65,7 +65,8 @@
binder::ProcessState::start_thread_pool();
// Register the service
- let local_ta = LocalTa::new();
+ let local_ta =
+ LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
let service = service::AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
let service_name = format!("{}/{}", SERVICE_NAME, SERVICE_INSTANCE);
binder::add_service(&service_name, service.as_binder()).map_err(|e| {
diff --git a/tests/multithread/1.0/default/Multithread.h b/tests/multithread/1.0/default/Multithread.h
index 0d4a007..7df75cc 100644
--- a/tests/multithread/1.0/default/Multithread.h
+++ b/tests/multithread/1.0/default/Multithread.h
@@ -33,7 +33,7 @@
std::condition_variable mCv;
std::mutex mCvMutex;
- static constexpr auto kTimeoutDuration = 100ms;
+ static constexpr auto kTimeoutDuration = 1000ms;
};
extern "C" IMultithread* HIDL_FETCH_IMultithread(const char* name);