Merge "Support to get EC public key from the UdsCertchain."
diff --git a/audio/common/all-versions/test/utility/Android.bp b/audio/common/all-versions/test/utility/Android.bp
index 757f8a8..c6a3963 100644
--- a/audio/common/all-versions/test/utility/Android.bp
+++ b/audio/common/all-versions/test/utility/Android.bp
@@ -62,6 +62,5 @@
"libxml2",
"liblog",
],
- static_libs: ["libgtest"],
test_suites: ["general-tests"],
}
diff --git a/bluetooth/audio/aidl/TEST_MAPPING b/bluetooth/audio/aidl/TEST_MAPPING
new file mode 100644
index 0000000..0c853f8
--- /dev/null
+++ b/bluetooth/audio/aidl/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalBluetoothAudioTargetTest"
+ }
+ ],
+ "kernel-presubmit": [
+ {
+ "name": "VtsHalBluetoothAudioTargetTest"
+ }
+ ]
+}
diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
index 4fc7437..04db7f3 100644
--- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
@@ -18,15 +18,16 @@
//#define LOG_NDEBUG 0
#include <log/log.h>
-#include <regex>
-#include <sys/inotify.h>
+#include <cutils/properties.h>
#include <errno.h>
#include <linux/videodev2.h>
-#include <cutils/properties.h>
-#include "ExternalCameraProviderImpl_2_4.h"
+#include <sys/inotify.h>
+#include <regex>
+#include <string>
#include "ExternalCameraDevice_3_4.h"
#include "ExternalCameraDevice_3_5.h"
#include "ExternalCameraDevice_3_6.h"
+#include "ExternalCameraProviderImpl_2_4.h"
namespace android {
namespace hardware {
@@ -41,10 +42,10 @@
// "device@<version>/external/<id>"
const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)");
const int kMaxDevicePathLen = 256;
-const char* kDevicePath = "/dev/";
-constexpr char kPrefix[] = "video";
-constexpr int kPrefixLen = sizeof(kPrefix) - 1;
-constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1;
+constexpr const char* kDevicePath = "/dev/";
+constexpr const char* kPrefix = "video";
+constexpr int kPrefixLen = std::char_traits<char>::length(kPrefix);
+constexpr int kDevicePrefixLen = std::char_traits<char>::length(kDevicePath) + kPrefixLen;
bool matchDeviceName(int cameraIdOffset,
const hidl_string& deviceName, std::string* deviceVersion,
diff --git a/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp b/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp
index b63e3bb..62ce074 100644
--- a/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp
+++ b/camera/provider/2.7/default/ExternalCameraProviderImpl_2_7.cpp
@@ -23,6 +23,7 @@
#include <linux/videodev2.h>
#include <sys/inotify.h>
#include <regex>
+#include <string>
#include "ExternalCameraDevice_3_4.h"
#include "ExternalCameraDevice_3_5.h"
#include "ExternalCameraDevice_3_6.h"
@@ -39,10 +40,10 @@
// "device@<version>/external/<id>"
const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)");
const int kMaxDevicePathLen = 256;
-const char* kDevicePath = "/dev/";
-constexpr char kPrefix[] = "video";
-constexpr int kPrefixLen = sizeof(kPrefix) - 1;
-constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1;
+constexpr const char* kDevicePath = "/dev/";
+constexpr const char* kPrefix = "video";
+constexpr int kPrefixLen = std::char_traits<char>::length(kPrefix);
+constexpr int kDevicePrefixLen = std::char_traits<char>::length(kDevicePath) + kPrefixLen;
bool matchDeviceName(int cameraIdOffset, const hidl_string& deviceName, std::string* deviceVersion,
std::string* cameraDevicePath) {
diff --git a/camera/provider/aidl/vts/Android.bp b/camera/provider/aidl/vts/Android.bp
index f17de3a..647cbac 100644
--- a/camera/provider/aidl/vts/Android.bp
+++ b/camera/provider/aidl/vts/Android.bp
@@ -68,6 +68,16 @@
"libgralloctypes",
"libaidlcommonsupport",
],
+
+ require_root: true,
+ test_options: {
+ test_runner_options: [
+ {
+ name: "native-test-timeout",
+ value: "1800000",
+ },
+ ],
+ },
test_suites: [
"general-tests",
"vts",
diff --git a/camera/provider/aidl/vts/AndroidTest.xml b/camera/provider/aidl/vts/AndroidTest.xml
deleted file mode 100644
index 226121d..0000000
--- a/camera/provider/aidl/vts/AndroidTest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 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.
--->
-<configuration description="Runs VtsAidlHalCameraProvider_TargetTest.">
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="apct-native" />
-
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
- </target_preparer>
-
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="push" value="VtsAidlHalCameraProvider_TargetTest->/data/local/tmp/VtsAidlHalCameraProvider_TargetTest" />
- </target_preparer>
-
- <test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="VtsAidlHalCameraProvider_TargetTest" />
- <option name="native-test-timeout" value="1800000"/> <!-- 30 min -->
- </test>
-</configuration>
\ No newline at end of file
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 9b9506d..e23f2ae 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -134,7 +134,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.biometrics.face</name>
<version>2</version>
<interface>
@@ -142,7 +142,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.biometrics.fingerprint</name>
<version>2</version>
<interface>
@@ -150,14 +150,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.bluetooth</name>
- <version>1.0-1</version>
- <interface>
- <name>IBluetoothHci</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.bluetooth</name>
<interface>
@@ -637,14 +629,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.soundtrigger</name>
- <version>2.3</version>
- <interface>
- <name>ISoundTriggerHw</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.soundtrigger3</name>
<version>1</version>
@@ -653,22 +637,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.tetheroffload.config</name>
- <version>1.0</version>
- <interface>
- <name>IOffloadConfig</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.tetheroffload.control</name>
- <version>1.1</version>
- <interface>
- <name>IOffloadControl</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.tetheroffload</name>
<version>1</version>
diff --git a/graphics/composer/2.4/vts/functional/TEST_MAPPING b/graphics/composer/2.4/vts/functional/TEST_MAPPING
new file mode 100644
index 0000000..aedac5b
--- /dev/null
+++ b/graphics/composer/2.4/vts/functional/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalGraphicsComposerV2_4TargetTest"
+ }
+ ],
+ "kernel-presubmit": [
+ {
+ "name": "VtsHalGraphicsComposerV2_4TargetTest"
+ }
+ ]
+}
+
diff --git a/keymaster/TEST_MAPPING b/keymaster/TEST_MAPPING
new file mode 100644
index 0000000..8cbf3e1
--- /dev/null
+++ b/keymaster/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalKeymasterV3_0TargetTest"
+ },
+ {
+ "name": "VtsHalKeymasterV4_0TargetTest"
+ },
+ {
+ "name": "VtsHalKeymasterV4_1TargetTest"
+ }
+ ]
+}
diff --git a/media/bufferpool/aidl/Android.bp b/media/bufferpool/aidl/Android.bp
index 68ac489..5ea2948 100644
--- a/media/bufferpool/aidl/Android.bp
+++ b/media/bufferpool/aidl/Android.bp
@@ -24,6 +24,7 @@
aidl_interface {
name: "android.hardware.media.bufferpool2",
vendor_available: true,
+ double_loadable: true,
srcs: ["android/hardware/media/bufferpool2/*.aidl"],
imports: [
"android.hardware.common-V2",
diff --git a/media/c2/aidl/Android.bp b/media/c2/aidl/Android.bp
index 3393ede..75d74ac 100644
--- a/media/c2/aidl/Android.bp
+++ b/media/c2/aidl/Android.bp
@@ -12,9 +12,10 @@
aidl_interface {
name: "android.hardware.media.c2",
vendor_available: true,
+ double_loadable: true,
srcs: ["android/hardware/media/c2/*.aidl"],
include_dirs: [
- "frameworks/native/aidl/gui",
+ "frameworks/base/core/java",
],
imports: [
"android.hardware.common-V2",
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
index d0e4cbf..909476c 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
@@ -43,16 +43,16 @@
@Backing(type="int") @VintfStability
enum Type {
NO_INIT = 0,
- INT32 = 1,
- UINT32 = 2,
- CNTR32 = 3,
- INT64 = 4,
- UINT64 = 5,
- CNTR64 = 6,
- FLOAT = 7,
- STRING = 256,
- BLOB = 257,
- STRUCT = 131072,
+ INT32,
+ UINT32,
+ CNTR32,
+ INT64,
+ UINT64,
+ CNTR64,
+ FLOAT,
+ STRING = 0x100,
+ BLOB,
+ STRUCT = 0x20000,
}
@VintfStability
parcelable NamedValue {
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
index 22f7c84..6a5fbe2 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
@@ -39,6 +39,6 @@
@Backing(type="int") @VintfStability
enum Type {
POSSIBLE = 0,
- CURRENT = 1,
+ CURRENT,
}
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
index e73b05e..07bfb72 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
@@ -39,9 +39,9 @@
android.hardware.media.c2.Buffer[] buffers;
android.hardware.media.c2.Params configUpdate;
android.hardware.media.c2.InfoBuffer[] infoBuffers;
- const int DROP_FRAME = 1;
- const int END_OF_STREAM = 2;
- const int DISCARD_FRAME = 4;
- const int FLAG_INCOMPLETE = 8;
- const int CODEC_CONFIG = -2147483648;
+ const int DROP_FRAME = (1 << 0) /* 1 */;
+ const int END_OF_STREAM = (1 << 1) /* 2 */;
+ const int DISCARD_FRAME = (1 << 2) /* 4 */;
+ const int FLAG_INCOMPLETE = (1 << 3) /* 8 */;
+ const int CODEC_CONFIG = (1 << 31) /* -2147483648 */;
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
index 7ed09af..1af66d0 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
@@ -43,7 +43,7 @@
void queue(in android.hardware.media.c2.WorkBundle workBundle);
void release();
void reset();
- void setOutputSurface(in long blockPoolId, in android.view.Surface surface, in android.hardware.media.c2.SurfaceSyncObj syncObject);
+ void setDecoderOutputAllocator(in android.hardware.media.c2.IGraphicBufferAllocator allocator);
void start();
void stop();
parcelable BlockPool {
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
index 35532be..d1b5915 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
@@ -52,15 +52,15 @@
@Backing(type="int") @VintfStability
enum Kind {
OTHER = 0,
- DECODER = 1,
- ENCODER = 2,
+ DECODER,
+ ENCODER,
}
@Backing(type="int") @VintfStability
enum Domain {
OTHER = 0,
- VIDEO = 1,
- AUDIO = 2,
- IMAGE = 3,
+ VIDEO,
+ AUDIO,
+ IMAGE,
}
}
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
similarity index 72%
rename from media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
rename to media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
index 1c9bf8d..da3d5ff 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -33,9 +33,22 @@
package android.hardware.media.c2;
@VintfStability
-parcelable SurfaceSyncObj {
- android.hardware.common.NativeHandle syncMemory;
- long bqId;
- int generationId;
- long consumerUsage;
+interface IGraphicBufferAllocator {
+ android.hardware.media.c2.IGraphicBufferAllocator.Allocation allocate(in android.hardware.media.c2.IGraphicBufferAllocator.Description desc);
+ boolean deallocate(in long id);
+ android.hardware.media.c2.IGraphicBufferAllocator.WaitableFds getWaitableFds();
+ parcelable Allocation {
+ android.hardware.HardwareBuffer buffer;
+ ParcelFileDescriptor fence;
+ }
+ parcelable Description {
+ int width;
+ int height;
+ int format;
+ long usage;
+ }
+ parcelable WaitableFds {
+ ParcelFileDescriptor allocEvent;
+ ParcelFileDescriptor statusEvent;
+ }
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
index 04c869c..6f0ac50 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
@@ -38,11 +38,11 @@
int attrib;
String name;
int[] dependencies;
- const int ATTRIBUTE_REQUIRED = 1;
- const int ATTRIBUTE_PERSISTENT = 2;
- const int ATTRIBUTE_STRICT = 4;
- const int ATTRIBUTE_READ_ONLY = 8;
- const int ATTRIBUTE_HIDDEN = 16;
- const int ATTRIBUTE_INTERNAL = 32;
- const int ATTRIBUTE_CONST = 64;
+ const int ATTRIBUTE_REQUIRED = (1 << 0) /* 1 */;
+ const int ATTRIBUTE_PERSISTENT = (1 << 1) /* 2 */;
+ const int ATTRIBUTE_STRICT = (1 << 2) /* 4 */;
+ const int ATTRIBUTE_READ_ONLY = (1 << 3) /* 8 */;
+ const int ATTRIBUTE_HIDDEN = (1 << 4) /* 16 */;
+ const int ATTRIBUTE_INTERNAL = (1 << 5) /* 32 */;
+ const int ATTRIBUTE_CONST = (1 << 6) /* 64 */;
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
index f9e6a93..07fc1f3 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
@@ -39,15 +39,15 @@
android.hardware.media.c2.ParamFieldValues[] conflicts;
@Backing(type="int") @VintfStability
enum Failure {
- BAD_TYPE = 0,
- BAD_PORT = 1,
- BAD_INDEX = 2,
- READ_ONLY = 3,
- MISMATCH = 4,
- BAD_VALUE = 5,
- CONFLICT = 6,
- UNSUPPORTED = 7,
- INFO_BAD_VALUE = 8,
- INFO_CONFLICT = 9,
+ BAD_TYPE,
+ BAD_PORT,
+ BAD_INDEX,
+ READ_ONLY,
+ MISMATCH,
+ BAD_VALUE,
+ CONFLICT,
+ UNSUPPORTED,
+ INFO_BAD_VALUE,
+ INFO_CONFLICT,
}
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
index ad07677..8b430d2 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
@@ -36,17 +36,17 @@
parcelable Status {
int status;
const int OK = 0;
- const int BAD_VALUE = -22;
- const int BAD_INDEX = -75;
- const int CANNOT_DO = -2147483646;
- const int DUPLICATE = -17;
- const int NOT_FOUND = -2;
- const int BAD_STATE = -38;
- const int BLOCKING = -9930;
- const int NO_MEMORY = -12;
- const int REFUSED = -1;
- const int TIMED_OUT = -110;
- const int OMITTED = -74;
- const int CORRUPTED = -2147483648;
- const int NO_INIT = -19;
+ const int BAD_VALUE = (-22) /* -22 */;
+ const int BAD_INDEX = (-75) /* -75 */;
+ const int CANNOT_DO = (-2147483646) /* -2147483646 */;
+ const int DUPLICATE = (-17) /* -17 */;
+ const int NOT_FOUND = (-2) /* -2 */;
+ const int BAD_STATE = (-38) /* -38 */;
+ const int BLOCKING = (-9930) /* -9930 */;
+ const int NO_MEMORY = (-12) /* -12 */;
+ const int REFUSED = (-1) /* -1 */;
+ const int TIMED_OUT = (-110) /* -110 */;
+ const int OMITTED = (-74) /* -74 */;
+ const int CORRUPTED = (-2147483648) /* -2147483648 */;
+ const int NO_INIT = (-19) /* -19 */;
}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
index b3390c3..a9fddbb 100644
--- a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
+++ b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
@@ -17,12 +17,10 @@
package android.hardware.media.c2;
import android.hardware.common.NativeHandle;
-import android.view.Surface;
-
import android.hardware.media.c2.IComponentInterface;
import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.IGraphicBufferAllocator;
import android.hardware.media.c2.WorkBundle;
-import android.hardware.media.c2.SurfaceSyncObj;
/**
* Interface for an AIDL Codec2 component.
@@ -234,23 +232,15 @@
void reset();
/**
- * Starts using a surface for output with a synchronization object
+ * Specify an allocator for decoder output buffer from HAL.
*
- * This method must not block.
- *
- * @param blockPoolId Id of the `C2BlockPool` to be associated with the
- * output surface.
- * @param surface Output surface.
- * @param syncObject synchronization object for buffer allocation between
- * Framework and Component.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::CANNOT_DO` - The component does not support an output surface.
- * - `Status::REFUSED` - The output surface cannot be accessed.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * The method will be used once during the life-cycle of a codec instance.
+ * @param allocator Decoder output buffer allocator from the client
+ * @throws ServiceSpecificException with one of the following values
+ * - `Status::CANNOT_DO` - The component does not support allocating from the client.
* - `Status::CORRUPTED` - Some unknown error occurred.
*/
- void setOutputSurface(in long blockPoolId, in Surface surface,
- in SurfaceSyncObj syncObject);
+ void setDecoderOutputAllocator(in IGraphicBufferAllocator allocator);
/**
* Starts the component.
diff --git a/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl b/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl
new file mode 100644
index 0000000..1c97214
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl
@@ -0,0 +1,114 @@
+/*
+ * 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.media.c2;
+
+import android.hardware.HardwareBuffer;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Interface for decoder output buffer allocator for HAL process
+ *
+ * A graphic buffer for decoder output is allocated by the interface.
+ */
+@VintfStability
+interface IGraphicBufferAllocator {
+ /**
+ * A graphic buffer allocation.
+ *
+ * buffer is in android.hardware.HardwareBuffer.
+ * fence is provided in order to signal readiness of the buffer I/O inside
+ * underlying Graphics subsystem. This is called a sync fence throughout Android framework.
+ */
+ parcelable Allocation {
+ HardwareBuffer buffer;
+ ParcelFileDescriptor fence;
+ }
+
+ /**
+ * Parameters for a graphic buffer allocation.
+ *
+ * Refer to AHardwareBuffer_Desc(libnativewindow) for details.
+ */
+ parcelable Description {
+ int width;
+ int height;
+ int format;
+ long usage;
+ }
+
+ /**
+ * Allocate a graphic buffer.
+ *
+ * @param desc Allocation parameters.
+ * @return an android.hardware.HardwareBuffer which is basically same to
+ * AHardwareBuffer. If underlying grpahics system is blocked, c2::Status::Blocked
+ * will be returned. In this case getWaitableFds() will return file descriptors which
+ * can be used to construct a waitable object. The waitable object will be notified
+ * when underlying graphics system is unblocked
+ * @throws ServiceSpecificException with one of the following values:
+ * - `c2::Status::BAD_STATE` - The client is not in running states.
+ * - `c2::Status::BLOCKED` - Underlying graphics system is blocked.
+ * - `c2::Status::CORRUPTED` - Some unknown error occurred.
+ */
+ Allocation allocate(in Description desc);
+
+ /**
+ * De-allocate a graphic buffer by graphic buffer's unique id.
+ *
+ * @param id graphic buffer's unique id. See also AHardwareBuffer_getId().
+ * @return {@code true} when de-allocate happened, {@code false} otherwise.
+ */
+ boolean deallocate(in long id);
+
+ /**
+ * Fds for waitable object events.
+ *
+ * Fds are created by eventfd() with semaphore mode.
+ * For allocEvent, An integer counter regarding dequeuable buffer count is maintained
+ * by client using read()/write() to the fd. The fd can be checked whether it is
+ * readable via poll(). When in readable status, the specified counter is positive
+ * so allocate/dequeue can happen.
+ *
+ * For statusEvent, the client can notify further allocation is not feasible.
+ * e.g.) life-cycle of the underlying allocator is ended.
+ *
+ * C2Fence object should be implemented based on this Fds. Thus, C2Fence can return
+ * either by allocation being ready or allocation being infeasible by the client status
+ * change.
+ */
+ parcelable WaitableFds {
+ ParcelFileDescriptor allocEvent;
+ ParcelFileDescriptor statusEvent;
+ }
+
+ /**
+ * Gets waiable file descriptors.
+ *
+ * Use this method once and cache it in order not to create unnecessary duplicated fds.
+ * The returned array will have two fds.
+ *
+ * If many waitable objects based on the same fd are competing, all watiable objects will be
+ * notified. After being notified, they should invoke allocate(). At least one of them can
+ * successfully allocate. Others not having an Allocation will have c2::Status::BLOCKED
+ * as return value. They should wait again via waitable objects based on the fds which are
+ * already returned from this interface.
+ *
+ * @return an fd array which will be wrapped to C2Fence and will be waited for
+ * until allocating is unblocked.
+ */
+ WaitableFds getWaitableFds();
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl b/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
deleted file mode 100644
index d20e102..0000000
--- a/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2022 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.media.c2;
-
-import android.hardware.common.NativeHandle;
-/**
- * Surface(BufferQueue/IGBP) synchronization object regarding # of dequeued
- * output buffers. This keeps # of dequeued buffers from Surface less than
- * configured max # of dequeued buffers all the time.
- */
-@VintfStability
-parcelable SurfaceSyncObj {
- /**
- * ASharedMemory for synchronization data. Layout is below
- *
- * |lock(futex) 4bytes|
- * |conditional_variable(futex) 4bytes|
- * |# of max dequeable buffer 4bytes|
- * |# of dequeued buffer 4bytes|
- * |Status of the surface 4bytes|
- * INIT = 0, Configuring surface is not finished.
- * ACTIVE = 1, Surface is ready to allocate(dequeue).
- * SWITCHING = 2, Switching to the new surface. It is blocked
- * to allocate(dequeue) a buffer until switching
- * completes.
- */
- NativeHandle syncMemory;
- /**
- * BufferQueue id.
- */
- long bqId;
- /**
- * Generation id.
- */
- int generationId;
- /**
- * Consumer usage flags. See +ndk
- * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
- */
- long consumerUsage;
-}
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index a868c96..c25c9ac 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -120,6 +120,7 @@
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
&attest_key_characteristics, &attest_key_cert_chain));
+ KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
ASSERT_GT(attest_key_cert_chain.size(), 0);
EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -141,8 +142,7 @@
.SetDefaultValidity(),
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
-
- CheckedDeleteKey(&attested_key_blob);
+ KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -174,8 +174,7 @@
.SetDefaultValidity(),
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
-
- CheckedDeleteKey(&attested_key_blob);
+ KeyBlobDeleter attested_deleter2(keymint_, attested_key_blob);
hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -207,6 +206,7 @@
.SetDefaultValidity(),
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
+ KeyBlobDeleter attested_deleter3(keymint_, attested_key_blob);
// The returned key characteristics will include CREATION_DATETIME (checked below)
// in SecurityLevel::KEYSTORE; this will be stripped out in the CheckCharacteristics()
@@ -214,9 +214,6 @@
// 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);
@@ -308,6 +305,7 @@
if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
}
ASSERT_EQ(ErrorCode::OK, result);
+ KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
EXPECT_GT(attest_key_cert_chain.size(), 1);
verify_subject_and_serial(attest_key_cert_chain[0], serial_int, subject, false);
@@ -344,9 +342,7 @@
.SetDefaultValidity(),
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
-
- CheckedDeleteKey(&attested_key_blob);
- CheckedDeleteKey(&attest_key.keyBlob);
+ KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
AuthorizationSet hw_enforced2 = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced2 = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -376,6 +372,7 @@
const int chain_size = 6;
vector<vector<uint8_t>> key_blob_list(chain_size);
vector<vector<Certificate>> cert_chain_list(chain_size);
+ vector<KeyBlobDeleter> deleters;
for (int i = 0; i < chain_size; i++) {
string sub = "attest key chaining ";
@@ -412,6 +409,7 @@
if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
}
ASSERT_EQ(ErrorCode::OK, result);
+ deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -437,10 +435,6 @@
EXPECT_GT(cert_chain_list[i].size(), i + 1);
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
}
-
- for (int i = 0; i < chain_size; i++) {
- CheckedDeleteKey(&key_blob_list[i]);
- }
}
/*
@@ -453,6 +447,7 @@
const int chain_size = 6;
vector<vector<uint8_t>> key_blob_list(chain_size);
vector<vector<Certificate>> cert_chain_list(chain_size);
+ vector<KeyBlobDeleter> deleters;
for (int i = 0; i < chain_size; i++) {
string sub = "Ec attest key chaining ";
@@ -489,6 +484,7 @@
if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
}
ASSERT_EQ(ErrorCode::OK, result);
+ deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -514,10 +510,6 @@
EXPECT_GT(cert_chain_list[i].size(), i + 1);
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
}
-
- for (int i = 0; i < chain_size; i++) {
- CheckedDeleteKey(&key_blob_list[i]);
- }
}
/*
@@ -557,6 +549,7 @@
const int chain_size = 6;
vector<vector<uint8_t>> key_blob_list(chain_size);
vector<vector<Certificate>> cert_chain_list(chain_size);
+ vector<KeyBlobDeleter> deleters;
for (int i = 0; i < chain_size; i++) {
string sub = "Alt attest key chaining ";
@@ -607,6 +600,7 @@
if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
}
ASSERT_EQ(ErrorCode::OK, result);
+ deleters.push_back(KeyBlobDeleter(keymint_, key_blob_list[i]));
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -632,10 +626,6 @@
EXPECT_GT(cert_chain_list[i].size(), i + 1);
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
}
-
- for (int i = 0; i < chain_size; i++) {
- CheckedDeleteKey(&key_blob_list[i]);
- }
}
TEST_P(AttestKeyTest, MissingChallenge) {
@@ -653,6 +643,7 @@
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
&attest_key_characteristics, &attest_key_cert_chain));
+ KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
EXPECT_EQ(attest_key_cert_chain.size(), 1);
EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)) << "Failed on size " << size;
@@ -681,8 +672,6 @@
.SetDefaultValidity(),
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
-
- CheckedDeleteKey(&attest_key.keyBlob);
}
}
@@ -700,6 +689,7 @@
AuthorizationSetBuilder().EcdsaKey(curve).AttestKey().SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
&attest_key_characteristics, &attest_key_cert_chain));
+ KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
ASSERT_GT(attest_key_cert_chain.size(), 0);
EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -721,9 +711,9 @@
.SetDefaultValidity(),
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
+ KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
ASSERT_GT(attested_key_cert_chain.size(), 0);
- CheckedDeleteKey(&attested_key_blob);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -752,10 +742,9 @@
.SetDefaultValidity(),
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
+ KeyBlobDeleter attested_deleter2(keymint_, attested_key_blob);
ASSERT_GT(attested_key_cert_chain.size(), 0);
- CheckedDeleteKey(&attested_key_blob);
- CheckedDeleteKey(&attest_key.keyBlob);
hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -825,6 +814,7 @@
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
&attest_key_characteristics, &attest_key_cert_chain));
+ KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
ASSERT_GT(attest_key_cert_chain.size(), 0);
EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -891,8 +881,7 @@
}
ASSERT_EQ(result, ErrorCode::OK);
-
- CheckedDeleteKey(&attested_key_blob);
+ KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -906,7 +895,6 @@
hw_enforced, SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
}
- CheckedDeleteKey(&attest_key.keyBlob);
}
TEST_P(AttestKeyTest, EcdsaAttestationMismatchID) {
@@ -921,6 +909,7 @@
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
&attest_key_characteristics, &attest_key_cert_chain));
+ KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
ASSERT_GT(attest_key_cert_chain.size(), 0);
EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -966,7 +955,6 @@
<< "result = " << result;
device_id_attestation_vsr_check(result);
}
- CheckedDeleteKey(&attest_key.keyBlob);
}
TEST_P(AttestKeyTest, SecondIMEIAttestationIDSuccess) {
@@ -997,6 +985,7 @@
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
&attest_key_characteristics, &attest_key_cert_chain));
+ KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
EXPECT_EQ(attest_key_cert_chain.size(), 1);
EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));
@@ -1025,11 +1014,10 @@
}
ASSERT_EQ(result, ErrorCode::OK);
+ KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
device_id_attestation_vsr_check(result);
- CheckedDeleteKey(&attested_key_blob);
-
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -1043,8 +1031,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
hw_enforced, SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
-
- CheckedDeleteKey(&attest_key.keyBlob);
}
TEST_P(AttestKeyTest, MultipleIMEIAttestationIDSuccess) {
@@ -1081,6 +1067,7 @@
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
&attest_key_characteristics, &attest_key_cert_chain));
+ KeyBlobDeleter attest_deleter(keymint_, attest_key.keyBlob);
attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
EXPECT_EQ(attest_key_cert_chain.size(), 1);
EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));
@@ -1106,11 +1093,10 @@
}
ASSERT_EQ(result, ErrorCode::OK);
+ KeyBlobDeleter attested_deleter(keymint_, attested_key_blob);
device_id_attestation_vsr_check(result);
- CheckedDeleteKey(&attested_key_blob);
-
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -1127,8 +1113,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
hw_enforced, SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
-
- CheckedDeleteKey(&attest_key.keyBlob);
}
INSTANTIATE_KEYMINT_AIDL_TEST(AttestKeyTest);
diff --git a/security/keymint/aidl/vts/functional/AuthTest.cpp b/security/keymint/aidl/vts/functional/AuthTest.cpp
index 78c88f4..290e8fc 100644
--- a/security/keymint/aidl/vts/functional/AuthTest.cpp
+++ b/security/keymint/aidl/vts/functional/AuthTest.cpp
@@ -93,17 +93,21 @@
void TearDown() {
if (gk_ == nullptr) return;
gk_->deleteUser(uid_);
+ if (alt_uid_ != 0) {
+ gk_->deleteUser(alt_uid_);
+ }
}
bool GatekeeperAvailable() { return (gk_ != nullptr) || (hidl_gk_ != nullptr); }
- std::optional<GatekeeperEnrollResponse> doEnroll(const std::vector<uint8_t>& newPwd,
+ std::optional<GatekeeperEnrollResponse> doEnroll(uint32_t uid,
+ const std::vector<uint8_t>& newPwd,
const std::vector<uint8_t>& curHandle = {},
const std::vector<uint8_t>& curPwd = {}) {
if (gk_ != nullptr) {
while (true) {
GatekeeperEnrollResponse rsp;
- Status status = gk_->enroll(uid_, curHandle, curPwd, newPwd, &rsp);
+ Status status = gk_->enroll(uid, curHandle, curPwd, newPwd, &rsp);
if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
sleep(1);
@@ -120,7 +124,7 @@
while (true) {
HidlGatekeeperResponse rsp;
auto status = hidl_gk_->enroll(
- uid_, curHandle, curPwd, newPwd,
+ uid, curHandle, curPwd, newPwd,
[&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
if (!status.isOk()) {
GTEST_LOG_(ERROR) << "doEnroll(HIDL) failed";
@@ -155,20 +159,23 @@
}
}
- std::optional<GatekeeperEnrollResponse> doEnroll(const string& newPwd,
+ std::optional<GatekeeperEnrollResponse> doEnroll(uint32_t uid, const string& newPwd,
const std::vector<uint8_t>& curHandle = {},
const string& curPwd = {}) {
- return doEnroll(std::vector<uint8_t>(newPwd.begin(), newPwd.end()), curHandle,
+ return doEnroll(uid, std::vector<uint8_t>(newPwd.begin(), newPwd.end()), curHandle,
std::vector<uint8_t>(curPwd.begin(), curPwd.end()));
}
+ std::optional<GatekeeperEnrollResponse> doEnroll(const string& newPwd) {
+ return doEnroll(uid_, newPwd);
+ }
- std::optional<HardwareAuthToken> doVerify(uint64_t challenge,
+ std::optional<HardwareAuthToken> doVerify(uint32_t uid, uint64_t challenge,
const std::vector<uint8_t>& handle,
const std::vector<uint8_t>& pwd) {
if (gk_ != nullptr) {
while (true) {
GatekeeperVerifyResponse rsp;
- Status status = gk_->verify(uid_, challenge, handle, pwd, &rsp);
+ Status status = gk_->verify(uid, challenge, handle, pwd, &rsp);
if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
sleep(1);
@@ -185,7 +192,7 @@
while (true) {
HidlGatekeeperResponse rsp;
auto status = hidl_gk_->verify(
- uid_, challenge, handle, pwd,
+ uid, challenge, handle, pwd,
[&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
if (!status.isOk()) {
GTEST_LOG_(ERROR) << "doVerify(HIDL) failed";
@@ -220,10 +227,15 @@
return std::nullopt;
}
}
+ std::optional<HardwareAuthToken> doVerify(uint32_t uid, uint64_t challenge,
+ const std::vector<uint8_t>& handle,
+ const string& pwd) {
+ return doVerify(uid, challenge, handle, std::vector<uint8_t>(pwd.begin(), pwd.end()));
+ }
std::optional<HardwareAuthToken> doVerify(uint64_t challenge,
const std::vector<uint8_t>& handle,
const string& pwd) {
- return doVerify(challenge, handle, std::vector<uint8_t>(pwd.begin(), pwd.end()));
+ return doVerify(uid_, challenge, handle, pwd);
}
// Variants of the base class methods but with authentication information included.
@@ -268,6 +280,13 @@
return plaintext;
}
+ string SignMessage(const vector<uint8_t>& key_blob, const string& message,
+ const AuthorizationSet& in_params, AuthorizationSet* out_params,
+ const HardwareAuthToken& hat) {
+ SCOPED_TRACE("SignMessage");
+ return ProcessMessage(key_blob, KeyPurpose::SIGN, message, in_params, out_params, hat);
+ }
+
protected:
std::shared_ptr<IGatekeeper> gk_;
sp<IHidlGatekeeper> hidl_gk_;
@@ -275,6 +294,8 @@
string password_;
uint32_t uid_;
int64_t sid_;
+ uint32_t alt_uid_;
+ int64_t alt_sid_;
std::vector<uint8_t> handle_;
};
@@ -347,6 +368,116 @@
}
}
+// Test use of a key that requires user-authentication within recent history, but where
+// the `TimestampToken` provided to the device is unrelated to the in-progress operation.
+TEST_P(AuthTest, TimeoutAuthenticationIncorrectTimestampToken) {
+ if (!GatekeeperAvailable()) {
+ GTEST_SKIP() << "No Gatekeeper available";
+ }
+ if (!timestamp_token_required_) {
+ GTEST_SKIP() << "Test only applies to devices with no secure clock";
+ }
+ if (clock_ == nullptr) {
+ GTEST_SKIP() << "Device requires timestamps and no ISecureClock available";
+ }
+
+ // Create an AES key that requires authentication within the last 3 seconds.
+ const uint32_t timeout_secs = 3;
+ auto builder = AuthorizationSetBuilder()
+ .AesEncryptionKey(256)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::PKCS7)
+ .Authorization(TAG_USER_SECURE_ID, sid_)
+ .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD)
+ .Authorization(TAG_AUTH_TIMEOUT, timeout_secs);
+ vector<uint8_t> keyblob;
+ vector<KeyCharacteristics> key_characteristics;
+ vector<Certificate> cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+ // Verify to get a HAT, arbitrary challenge.
+ const uint64_t challenge = 42;
+ const std::optional<HardwareAuthToken> hat = doVerify(challenge, handle_, password_);
+ ASSERT_TRUE(hat.has_value());
+ EXPECT_EQ(hat->userId, sid_);
+
+ // KeyMint implementation has no clock, so only detects timeout via timestamp token provided
+ // on update()/finish(). However, for this test we ensure that that the timestamp token has a
+ // *different* challenge value.
+ const string message = "Hello World!";
+ auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ AuthorizationSet out_params;
+ ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, hat));
+
+ secureclock::TimeStampToken time_token;
+ EXPECT_EQ(ErrorCode::OK,
+ GetReturnErrorCode(clock_->generateTimeStamp(challenge_ + 1, &time_token)));
+ string output;
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+ Finish(message, {} /* signature */, &output, hat, time_token));
+}
+
+// Test use of a key with multiple USER_SECURE_ID values. For variety, use an EC signing key
+// generated with attestation.
+TEST_P(AuthTest, TimeoutAuthenticationMultiSid) {
+ if (!GatekeeperAvailable()) {
+ GTEST_SKIP() << "No Gatekeeper available";
+ }
+ if (timestamp_token_required_ && clock_ == nullptr) {
+ GTEST_SKIP() << "Device requires timestamps and no ISecureClock available";
+ }
+
+ // Enroll a password for a second user.
+ alt_uid_ = 20001;
+ const string alt_password = "correcthorsebatterystaple2";
+ std::optional<GatekeeperEnrollResponse> rsp = doEnroll(alt_uid_, alt_password);
+ ASSERT_TRUE(rsp.has_value());
+ alt_sid_ = rsp->secureUserId;
+ const std::vector<uint8_t> alt_handle = rsp->data;
+
+ // Create an attested EC key that requires authentication within the last 3 seconds from either
+ // secure ID. Also allow any authenticator type.
+ const uint32_t timeout_secs = 3;
+ auto builder = AuthorizationSetBuilder()
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::NONE)
+ .Digest(Digest::SHA_2_256)
+ .SetDefaultValidity()
+ .AttestationChallenge("challenge")
+ .AttestationApplicationId("app_id")
+ .Authorization(TAG_USER_SECURE_ID, alt_sid_)
+ .Authorization(TAG_USER_SECURE_ID, sid_)
+ .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::ANY)
+ .Authorization(TAG_AUTH_TIMEOUT, timeout_secs);
+ vector<uint8_t> keyblob;
+ vector<KeyCharacteristics> key_characteristics;
+ vector<Certificate> cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+ // Verify first user to get a HAT that should work.
+ const uint64_t challenge = 42;
+ const std::optional<HardwareAuthToken> hat = doVerify(uid_, challenge, handle_, password_);
+ ASSERT_TRUE(hat.has_value());
+ EXPECT_EQ(hat->userId, sid_);
+
+ const string message = "Hello World!";
+ auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
+ AuthorizationSet out_params;
+ const string signature = SignMessage(keyblob, message, params, &out_params, hat.value());
+
+ // Verify second user to get a HAT that should work.
+ const uint64_t alt_challenge = 43;
+ const std::optional<HardwareAuthToken> alt_hat =
+ doVerify(alt_uid_, alt_challenge, alt_handle, alt_password);
+ ASSERT_TRUE(alt_hat.has_value());
+ EXPECT_EQ(alt_hat->userId, alt_sid_);
+
+ const string alt_signature =
+ SignMessage(keyblob, message, params, &out_params, alt_hat.value());
+}
+
// Test use of a key that requires an auth token for each action on the operation, with
// a per-operation challenge value included.
TEST_P(AuthTest, AuthPerOperation) {
@@ -407,6 +538,93 @@
Finish(message, {} /* signature */, &ciphertext, hat.value()));
}
+// Test use of a key that requires an auth token for each action on the operation, with
+// a per-operation challenge value included, with multiple secure IDs allowed.
+TEST_P(AuthTest, AuthPerOperationMultiSid) {
+ if (!GatekeeperAvailable()) {
+ GTEST_SKIP() << "No Gatekeeper available";
+ }
+
+ // Enroll a password for a second user.
+ alt_uid_ = 20001;
+ const string alt_password = "correcthorsebatterystaple2";
+ std::optional<GatekeeperEnrollResponse> rsp = doEnroll(alt_uid_, alt_password);
+ ASSERT_TRUE(rsp.has_value());
+ alt_sid_ = rsp->secureUserId;
+ const std::vector<uint8_t> alt_handle = rsp->data;
+
+ // Create an AES key that requires authentication per-action.
+ auto builder = AuthorizationSetBuilder()
+ .AesEncryptionKey(256)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::PKCS7)
+ .Authorization(TAG_USER_SECURE_ID, sid_)
+ .Authorization(TAG_USER_SECURE_ID, alt_sid_)
+ .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::ANY);
+ vector<uint8_t> keyblob;
+ vector<KeyCharacteristics> key_characteristics;
+ vector<Certificate> cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+ // Get a HAT for first user with the challenge from an in-progress operation.
+ const string message = "Hello World!";
+ auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ AuthorizationSet out_params;
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+ const std::optional<HardwareAuthToken> hat = doVerify(uid_, challenge_, handle_, password_);
+ ASSERT_TRUE(hat.has_value());
+ EXPECT_EQ(hat->userId, sid_);
+ string ciphertext;
+ EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &ciphertext, hat.value()));
+
+ // Get a HAT for second user with the challenge from an in-progress operation.
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+ const std::optional<HardwareAuthToken> alt_hat =
+ doVerify(alt_uid_, challenge_, alt_handle, alt_password);
+ ASSERT_TRUE(alt_hat.has_value());
+ EXPECT_EQ(alt_hat->userId, alt_sid_);
+ string alt_ciphertext;
+ EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &ciphertext, alt_hat.value()));
+}
+
+// Test use of a key that requires an auth token for each action on the operation, but
+// which gets passed a HAT of the wrong type
+TEST_P(AuthTest, AuthPerOperationWrongAuthType) {
+ if (!GatekeeperAvailable()) {
+ GTEST_SKIP() << "No Gatekeeper available";
+ }
+
+ // Create an AES key that requires authentication per-action, but with no valid authenticator
+ // types.
+ auto builder =
+ AuthorizationSetBuilder()
+ .AesEncryptionKey(256)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::PKCS7)
+ .Authorization(TAG_USER_SECURE_ID, sid_)
+ .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::FINGERPRINT);
+ vector<uint8_t> keyblob;
+ vector<KeyCharacteristics> key_characteristics;
+ vector<Certificate> cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+ // Get a HAT with the challenge from an in-progress operation.
+ const string message = "Hello World!";
+ auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ AuthorizationSet out_params;
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+ const std::optional<HardwareAuthToken> hat = doVerify(challenge_, handle_, password_);
+ ASSERT_TRUE(hat.has_value());
+ EXPECT_EQ(hat->userId, sid_);
+
+ // Should fail because auth type doesn't (can't) match.
+ string ciphertext;
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+ Finish(message, {} /* signature */, &ciphertext, hat.value()));
+}
+
INSTANTIATE_KEYMINT_AIDL_TEST(AuthTest);
} // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
index 4f72f67..4830422 100644
--- a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
@@ -560,7 +560,7 @@
.SetDefaultValidity(),
attest_key, &attested_key_blob, &attested_key_characteristics,
&attested_key_cert_chain));
- CheckedDeleteKey(&attested_key_blob);
+ KeyBlobDeleter(keymint_, attested_key_blob);
} else {
FAIL() << "Unexpected name: " << name;
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index e51bb6e..b2fd08e 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -176,6 +176,17 @@
std::string KeyMintAidlTestBase::keyblob_dir;
std::optional<bool> KeyMintAidlTestBase::expect_upgrade = std::nullopt;
+KeyBlobDeleter::~KeyBlobDeleter() {
+ if (key_blob_.empty()) {
+ return;
+ }
+ Status result = keymint_->deleteKey(key_blob_);
+ key_blob_.clear();
+ EXPECT_TRUE(result.isOk()) << result.getServiceSpecificError() << "\n";
+ ErrorCode rc = GetReturnErrorCode(result);
+ EXPECT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED) << result << "\n";
+}
+
uint32_t KeyMintAidlTestBase::boot_patch_level(
const vector<KeyCharacteristics>& key_characteristics) {
// The boot patchlevel is not available as a property, but should be present
@@ -229,16 +240,6 @@
return version >= 2;
}
-ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(const Status& result) {
- if (result.isOk()) return ErrorCode::OK;
-
- if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
- return static_cast<ErrorCode>(result.getServiceSpecificError());
- }
-
- return ErrorCode::UNKNOWN_ERROR;
-}
-
void KeyMintAidlTestBase::InitializeKeyMint(std::shared_ptr<IKeyMintDevice> keyMint) {
ASSERT_NE(keyMint, nullptr);
keymint_ = std::move(keyMint);
@@ -513,13 +514,9 @@
return GetReturnErrorCode(result);
}
-void KeyMintAidlTestBase::CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
- ErrorCode result = DeleteKey(key_blob, keep_key_blob);
- EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl;
-}
-
void KeyMintAidlTestBase::CheckedDeleteKey() {
- CheckedDeleteKey(&key_blob_);
+ ErrorCode result = DeleteKey(&key_blob_, /* keep_key_blob = */ false);
+ EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl;
}
ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
@@ -1606,7 +1603,8 @@
auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr);
if (res <= 0) return false;
- const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"};
+ const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P",
+ "SM4450", "SM7450", "SM6450"};
for (const string model : allowed_soc_models) {
if (model.compare(buffer.data()) == 0) {
@@ -1985,6 +1983,16 @@
return AssertionSuccess();
}
+ErrorCode GetReturnErrorCode(const Status& result) {
+ if (result.isOk()) return ErrorCode::OK;
+
+ if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+ return static_cast<ErrorCode>(result.getServiceSpecificError());
+ }
+
+ return ErrorCode::UNKNOWN_ERROR;
+}
+
X509_Ptr parse_cert_blob(const vector<uint8_t>& blob) {
const uint8_t* p = blob.data();
return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size()));
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 415a83e..aa3069a 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -57,6 +57,18 @@
const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key";
const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
+// RAII class to ensure that a keyblob is deleted regardless of how a test exits.
+class KeyBlobDeleter {
+ public:
+ KeyBlobDeleter(const shared_ptr<IKeyMintDevice>& keymint, const vector<uint8_t>& key_blob)
+ : keymint_(keymint), key_blob_(key_blob) {}
+ ~KeyBlobDeleter();
+
+ private:
+ shared_ptr<IKeyMintDevice> keymint_;
+ vector<uint8_t> key_blob_;
+};
+
class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
public:
struct KeyData {
@@ -94,8 +106,6 @@
bool Curve25519Supported();
- ErrorCode GetReturnErrorCode(const Status& result);
-
ErrorCode GenerateKey(const AuthorizationSet& key_desc, vector<uint8_t>* key_blob,
vector<KeyCharacteristics>* key_characteristics) {
return GenerateKey(key_desc, std::nullopt /* attest_key */, key_blob, key_characteristics,
@@ -159,7 +169,6 @@
ErrorCode DestroyAttestationIds();
- void CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob = false);
void CheckedDeleteKey();
ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
@@ -431,6 +440,8 @@
::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
bool strict_issuer_check = true);
+ErrorCode GetReturnErrorCode(const Status& result);
+
#define INSTANTIATE_KEYMINT_AIDL_TEST(name) \
INSTANTIATE_TEST_SUITE_P(PerInstance, name, \
testing::ValuesIn(KeyMintAidlTestBase::build_params()), \
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index c54a2c9..c534a37 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -693,6 +693,7 @@
builder.Authorization(TAG_MIN_MAC_LENGTH, 128);
}
ASSERT_EQ(ErrorCode::OK, GenerateKey(builder, &key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
EXPECT_GT(key_blob.size(), 0U);
CheckSymmetricParams(key_characteristics);
@@ -703,8 +704,6 @@
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::AES));
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
<< "Key size " << key_size << "missing";
-
- CheckedDeleteKey(&key_blob);
}
}
}
@@ -877,6 +876,7 @@
.Authorization(TAG_NO_AUTH_REQUIRED)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
EXPECT_GT(key_blob.size(), 0U);
CheckSymmetricParams(key_characteristics);
@@ -887,8 +887,6 @@
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::TRIPLE_DES));
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
<< "Key size " << key_size << "missing";
-
- CheckedDeleteKey(&key_blob);
}
}
}
@@ -924,6 +922,7 @@
.AttestationApplicationId(app_id)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
EXPECT_GT(key_blob.size(), 0U);
CheckSymmetricParams(key_characteristics);
@@ -934,8 +933,6 @@
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::TRIPLE_DES));
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
<< "Key size " << key_size << "missing";
-
- CheckedDeleteKey(&key_blob);
}
}
}
@@ -1003,6 +1000,7 @@
.Padding(PaddingMode::NONE)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1014,8 +1012,6 @@
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1139,6 +1135,7 @@
}
}
ASSERT_EQ(ErrorCode::OK, result);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
CheckCharacteristics(key_blob, key_characteristics);
@@ -1159,8 +1156,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1214,6 +1209,7 @@
.Authorization(TAG_NO_AUTH_REQUIRED)
.SetDefaultValidity(),
attestation_key, &key_blob, &key_characteristics, &cert_chain_));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1240,8 +1236,6 @@
ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
<< "Verification of attested certificate failed "
<< "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1294,6 +1288,7 @@
.Authorization(TAG_NO_AUTH_REQUIRED)
.SetDefaultValidity(),
attestation_key, &key_blob, &key_characteristics, &cert_chain_));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1318,8 +1313,6 @@
ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
<< "Verification of attested certificate failed "
<< "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1365,6 +1358,7 @@
}
}
ASSERT_EQ(ErrorCode::OK, result);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
AuthorizationSet auths;
@@ -1405,8 +1399,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
-
- CheckedDeleteKey(&key_blob);
}
/*
@@ -1437,6 +1429,7 @@
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1452,8 +1445,6 @@
ASSERT_EQ(cert_chain_.size(), 1);
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1518,6 +1509,7 @@
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1534,8 +1526,6 @@
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
ASSERT_EQ(cert_chain_.size(), 1);
-
- CheckedDeleteKey(&key_blob);
}
/*
@@ -1556,6 +1546,7 @@
.Authorization(TAG_USAGE_COUNT_LIMIT, 1)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1575,8 +1566,6 @@
}
EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
<< "key usage count limit " << 1U << " missing";
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1625,6 +1614,7 @@
}
}
ASSERT_EQ(ErrorCode::OK, result);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1655,8 +1645,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1726,6 +1714,7 @@
.Digest(Digest::NONE)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
CheckCharacteristics(key_blob, key_characteristics);
@@ -1734,8 +1723,6 @@
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1759,6 +1746,8 @@
.SetDefaultValidity(),
&key_blob, &key_characteristics);
ASSERT_EQ(result, ErrorCode::OK);
+ KeyBlobDeleter deleter(keymint_, key_blob);
+
ASSERT_GT(key_blob.size(), 0U);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
@@ -1771,8 +1760,6 @@
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
-
- CheckedDeleteKey(&key_blob);
}
/*
@@ -1879,6 +1866,7 @@
}
}
ASSERT_EQ(ErrorCode::OK, result);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
CheckCharacteristics(key_blob, key_characteristics);
@@ -1897,8 +1885,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -1936,6 +1922,7 @@
.SetDefaultValidity(),
&key_blob, &key_characteristics);
ASSERT_EQ(ErrorCode::OK, result);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
CheckCharacteristics(key_blob, key_characteristics);
@@ -1954,8 +1941,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
-
- CheckedDeleteKey(&key_blob);
}
/*
@@ -2024,6 +2009,7 @@
}
}
ASSERT_EQ(result, ErrorCode::OK);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
@@ -2043,8 +2029,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
-
- CheckedDeleteKey(&key_blob);
}
// Collection of invalid attestation ID tags.
@@ -2170,6 +2154,7 @@
continue;
}
ASSERT_EQ(result, ErrorCode::OK);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
@@ -2189,8 +2174,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -2345,6 +2328,7 @@
}
}
ASSERT_EQ(result, ErrorCode::OK);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
@@ -2364,8 +2348,6 @@
ASSERT_EQ(std::search(cert_chain_[0].encodedCertificate.begin(),
cert_chain_[0].encodedCertificate.end(), needle.begin(), needle.end()),
cert_chain_[0].encodedCertificate.end());
-
- CheckedDeleteKey(&key_blob);
}
/*
@@ -2393,6 +2375,7 @@
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
CheckCharacteristics(key_blob, key_characteristics);
@@ -2408,8 +2391,6 @@
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -2463,6 +2444,7 @@
.AttestationApplicationId(app_id)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -2478,8 +2460,6 @@
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -2521,6 +2501,7 @@
}
}
ASSERT_EQ(ErrorCode::OK, result);
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
CheckCharacteristics(key_blob, key_characteristics);
@@ -2538,8 +2519,6 @@
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -2560,6 +2539,7 @@
.Authorization(TAG_USAGE_COUNT_LIMIT, 1)
.SetDefaultValidity(),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -2577,8 +2557,6 @@
}
EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
<< "key usage count limit " << 1U << " missing";
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -2710,6 +2688,7 @@
AuthorizationSetBuilder().HmacKey(key_size).Digest(digest).Authorization(
TAG_MIN_MAC_LENGTH, 128),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -2719,8 +2698,6 @@
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
<< "Key size " << key_size << "missing";
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -2746,6 +2723,7 @@
.AttestationApplicationId(app_id)
.Authorization(TAG_MIN_MAC_LENGTH, 128),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
ASSERT_EQ(cert_chain_.size(), 0);
@@ -2756,8 +2734,6 @@
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
<< "Key size " << key_size << "missing";
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -2779,6 +2755,7 @@
.Authorization(TAG_MIN_MAC_LENGTH, 128)
.Authorization(TAG_USAGE_COUNT_LIMIT, 1),
&key_blob, &key_characteristics));
+ KeyBlobDeleter deleter(keymint_, key_blob);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -2796,8 +2773,6 @@
}
EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
<< "key usage count limit " << 1U << " missing";
-
- CheckedDeleteKey(&key_blob);
}
}
@@ -3891,6 +3866,7 @@
.Digest(Digest::SHA_2_256)
.Authorization(TAG_MIN_MAC_LENGTH, 160),
KeyFormat::RAW, key_material, &signing_key, &signing_key_chars));
+ KeyBlobDeleter sign_deleter(keymint_, signing_key);
EXPECT_EQ(ErrorCode::OK,
ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -3899,6 +3875,7 @@
.Digest(Digest::SHA_2_256)
.Authorization(TAG_MIN_MAC_LENGTH, 160),
KeyFormat::RAW, key_material, &verification_key, &verification_key_chars));
+ KeyBlobDeleter verify_deleter(keymint_, verification_key);
string message = "This is a message.";
string signature = SignMessage(
@@ -3914,9 +3891,6 @@
// Verification key should work.
VerifyMessage(verification_key, message, signature,
AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
-
- CheckedDeleteKey(&signing_key);
- CheckedDeleteKey(&verification_key);
}
/*
@@ -3937,6 +3911,7 @@
.Digest(Digest::SHA_2_256)
.Authorization(TAG_MIN_MAC_LENGTH, 160),
KeyFormat::RAW, key_material, &signing_key, &signing_key_chars));
+ KeyBlobDeleter sign_deleter(keymint_, signing_key);
EXPECT_EQ(ErrorCode::OK,
ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -3945,6 +3920,7 @@
.Digest(Digest::SHA_2_256)
.Authorization(TAG_MIN_MAC_LENGTH, 160),
KeyFormat::RAW, key_material, &verification_key, &verification_key_chars));
+ KeyBlobDeleter verify_deleter(keymint_, verification_key);
string message = "This is a message.";
string signature = SignMessage(
@@ -3966,9 +3942,6 @@
signature[0] += 1; // Corrupt a signature
EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, signature, &output));
-
- CheckedDeleteKey(&signing_key);
- CheckedDeleteKey(&verification_key);
}
INSTANTIATE_KEYMINT_AIDL_TEST(VerificationOperationsTest);
@@ -8497,16 +8470,16 @@
// Early boot keys can be created after early boot.
auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK);
+ KeyBlobDeleter aes_deleter(keymint_, aesKeyData.blob);
+ KeyBlobDeleter hmac_deleter(keymint_, hmacKeyData.blob);
+ KeyBlobDeleter rsa_deleter(keymint_, rsaKeyData.blob);
+ KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
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);
}
/*
@@ -8520,6 +8493,10 @@
builder->AttestationChallenge("challenge");
builder->AttestationApplicationId("app_id");
});
+ KeyBlobDeleter aes_deleter(keymint_, aesKeyData.blob);
+ KeyBlobDeleter hmac_deleter(keymint_, hmacKeyData.blob);
+ KeyBlobDeleter rsa_deleter(keymint_, rsaKeyData.blob);
+ KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) {
// Strongbox may not support factory attestation. Key creation might fail with
@@ -8531,14 +8508,6 @@
AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics);
EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params;
}
- CheckedDeleteKey(&aesKeyData.blob);
- CheckedDeleteKey(&hmacKeyData.blob);
- if (rsaKeyData.blob.size() != 0U) {
- CheckedDeleteKey(&rsaKeyData.blob);
- }
- if (ecdsaKeyData.blob.size() != 0U) {
- CheckedDeleteKey(&ecdsaKeyData.blob);
- }
}
/*
@@ -8583,6 +8552,11 @@
TEST_P(EarlyBootKeyTest, DISABLED_FullTest) {
auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK);
+ KeyBlobDeleter aes_deleter(keymint_, aesKeyData.blob);
+ KeyBlobDeleter hmac_deleter(keymint_, hmacKeyData.blob);
+ KeyBlobDeleter rsa_deleter(keymint_, rsaKeyData.blob);
+ KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
+
// TAG_EARLY_BOOT_ONLY should be in hw-enforced.
EXPECT_TRUE(HwEnforcedAuthorizations(aesKeyData.characteristics).Contains(TAG_EARLY_BOOT_ONLY));
EXPECT_TRUE(
@@ -8607,19 +8581,13 @@
EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, UseRsaKey(rsaKeyData.blob));
EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, UseEcdsaKey(ecdsaKeyData.blob));
- CheckedDeleteKey(&aesKeyData.blob);
- CheckedDeleteKey(&hmacKeyData.blob);
- CheckedDeleteKey(&rsaKeyData.blob);
- CheckedDeleteKey(&ecdsaKeyData.blob);
-
// Should not be able to create new keys
- std::tie(aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData) =
+ auto [aesKeyData2, hmacKeyData2, rsaKeyData2, ecdsaKeyData2] =
CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::EARLY_BOOT_ENDED);
-
- CheckedDeleteKey(&aesKeyData.blob);
- CheckedDeleteKey(&hmacKeyData.blob);
- CheckedDeleteKey(&rsaKeyData.blob);
- CheckedDeleteKey(&ecdsaKeyData.blob);
+ KeyBlobDeleter aes_deleter2(keymint_, aesKeyData2.blob);
+ KeyBlobDeleter hmac_deleter2(keymint_, hmacKeyData2.blob);
+ KeyBlobDeleter rsa_deleter2(keymint_, rsaKeyData2.blob);
+ KeyBlobDeleter ecdsa_deleter2(keymint_, ecdsaKeyData2.blob);
}
INSTANTIATE_KEYMINT_AIDL_TEST(EarlyBootKeyTest);
@@ -8637,6 +8605,10 @@
TEST_P(UnlockedDeviceRequiredTest, DISABLED_KeysBecomeUnusable) {
auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
CreateTestKeys(TAG_UNLOCKED_DEVICE_REQUIRED, ErrorCode::OK);
+ KeyBlobDeleter aes_deleter(keymint_, aesKeyData.blob);
+ KeyBlobDeleter hmac_deleter(keymint_, hmacKeyData.blob);
+ KeyBlobDeleter rsa_deleter(keymint_, rsaKeyData.blob);
+ KeyBlobDeleter ecdsa_deleter(keymint_, ecdsaKeyData.blob);
EXPECT_EQ(ErrorCode::OK, UseAesKey(aesKeyData.blob));
EXPECT_EQ(ErrorCode::OK, UseHmacKey(hmacKeyData.blob));
@@ -8650,11 +8622,6 @@
EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseHmacKey(hmacKeyData.blob));
EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseRsaKey(rsaKeyData.blob));
EXPECT_EQ(ErrorCode::DEVICE_LOCKED, UseEcdsaKey(ecdsaKeyData.blob));
-
- CheckedDeleteKey(&aesKeyData.blob);
- CheckedDeleteKey(&hmacKeyData.blob);
- CheckedDeleteKey(&rsaKeyData.blob);
- CheckedDeleteKey(&ecdsaKeyData.blob);
}
INSTANTIATE_KEYMINT_AIDL_TEST(UnlockedDeviceRequiredTest);
diff --git a/security/rkp/README.md b/security/rkp/README.md
index a966141..f8e1d5e 100644
--- a/security/rkp/README.md
+++ b/security/rkp/README.md
@@ -3,7 +3,7 @@
## Objective
Design a HAL to support over-the-air provisioning of certificates for asymmetric
-keys. The HAL must interact effectively with Keystore (and other daemons) and
+keys. The HAL must interact effectively with Keystore (and other services) and
protect device privacy and security.
Note that this API was originally designed for KeyMint, with the intention that
@@ -20,125 +20,52 @@
To more securely and reliably get keys and certificates to Android devices, we
need to create a system where no party outside of the device's secure components
is responsible for managing private keys. The strategy we've chosen is to
-deliver certificates over the air, using an asymmetric key pair created
-on-device in the factory as a root of trust to create an authenticated, secure
-channel. In this document we refer to this device-unique asymmetric key pair as
-Device Key (DK), its public half DK\_pub, its private half DK\_priv and a Device
-Key Certificate containing DK\_pub is denoted DKC.
+deliver certificates over the air, using an asymmetric key pair derived from a
+unique device secret (UDS) as a root of trust for authenticated requests from
+the secure components. We refer to the public half of this asymmetric key pair
+as UDS\_pub.
-In order for the provisioning service to use DK (or a key authenticated by DK),
-it must know whether a given DK\_pub is known and trusted. To prove trust, we
-ask device OEMs to use one of two mechanisms:
+In order for the provisioning service to trust UDS\_pub we ask device OEMs to
+use one of two mechanisms:
-1. (Preferred, recommended) The device OEM extracts DK\_pub from each device it
- manufactures and uploads the public keys to a backend server.
+1. (Preferred, recommended) The device OEM extracts the UDS\_pub from each
+ device they manufacture and uploads the public keys to a backend server.
-1. The device OEM signs the DK\_pub to produce DKC and stores it on the device.
- This has the advantage that they don't need to upload a DK\_pub for every
- device immediately, but the disadvantage that they have to manage their
- private signing keys, which means they have to have HSMs, configure and
- secure them correctly, etc. Some backend providers may also require that the
- OEM passes a factory security audit, and additionally promises to upload the
- keys eventually as well.
+1. The device OEM signs the UDS\_pub and stores the certificates on the device
+ rather than uploading a UDS\_pub for every device immediately. However,
+ there are many disadvantages and costs associated with this option as the
+ OEM will need to pass a security audit of their factory's physical security,
+ CA and HSM configuration, and incident response processes before the OEM's
+ public key is registered with the provisioning server.
-Note that in the full elaboration of this plan, DK\_pub is not the key used to
-establish a secure channel. Instead, DK\_pub is just the first public key in a
-chain of public keys which ends with the KeyMint public key, KM\_pub. All keys
-in the chain are device-unique and are joined in a certificate chain called the
-_Boot Certificate Chain_ (BCC), because in phases 2 and 3 of the remote
-provisioning project it is a chain of certificates corresponding to boot phases.
-We speak of the BCC even for phase 1, though in phase 1 it contains only a
-single self-signed DKC. This is described in more depth in the Phases section
-below.
-
-The BCC is authenticated by DK\_pub. To authenticate DK\_pub, we may have
-additional DKCs, from the SoC vendor, the device OEM, or both. Those are not
-part of the BCC but included as optional fields in the certificate request
-structure.
-
-The format of the the DK and BCC is specified within [Open Profile for DICE]
-(https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md). To
-map phrases within this document to their equivalent terminology in the DICE
-specification, read the terms as follows: the DK corresponds to the UDS-derived
-key pair, DKC corresponds to the UDS certificate, and the BCC entries between
-DK\_pub and KM\_pub correspond to a chain of CDI certificates.
-
-Note: In addition to allowing 32 byte hash values for fields in the BCC payload,
-this spec additionally constrains some of the choices allowed in open-DICE.
-Specifically, these include which entries are required and which are optional in
-the BCC payload, and which algorithms are acceptable for use.
+Note that in the full elaboration of this plan, UDS\_pub is not the key used to
+sign certificate requests. Instead, UDS\_pub is just the first public key in a
+chain of public keys that end the KeyMint public key. All keys in the chain are
+transitively derived from the UDS and joined in a certificate chain following
+the specification of the [Android Profile for DICE](#android-profile-for-dice).
### Phases
-RKP will be deployed in three phases, in terms of managing the root of trust
+RKP will be deployed with phased management of the root of trust
binding between the device and the backend. To briefly describe them:
-* Phase 1: In phase 1 there is only one entry in the BCC; DK_pub and KM_pub are
- the same key and the certificate is self-signed.
-* Phase 2: This is identical to phase 1, except it leverages the hardware root
- of trust process described by DICE. Instead of trust being rooted in the TEE,
- it is now rooted in the ROM by key material blown into fuses which are only
- accessible to the ROM code.
-* Phase 3: This is identical to Phase 2, except the SoC vendor also does the
- public key extraction or certification in their facilities, along with the OEM
- doing it in the factory. This tightens up the "supply chain" and aims to make
- key upload management more secure.
+* Degenerate DICE (Phase 1): A TEE root of trust key pair is used to sign
+ certificate requests; a single self-signed certificate signifies this phase.
+* DICE (Phase 2): A hardware root of trust key pair is only accessible to ROM
+ code; the boot process follows the [Android Profile for
+ DICE](#android-profile-for-dice).
+* SoC vendor certified DICE (Phase 3): This is identical to Phase 2, except the
+ SoC vendor also does the UDS\_pub extraction or certification in their
+ facilities, along with the OEM doing it in the factory. This tightens up the
+ "supply chain" and aims to make key upload management more secure.
### Privacy considerations
-Because DK and the DKCs are unique, immutable, unspoofable hardware-bound
-identifiers for the device, we must limit access to them to the absolute minimum
-possible. We do this in two ways:
-
-1. We require KeyMint (which knows the BCC and either knows or at least has the
-ability to use KM\_priv) to refuse to ever divulge the BCC or additional
-signatures in plaintext. Instead, KeyMint requires the caller to provide an
-_Endpoint Encryption Key_ (EEK), with which it will encrypt the data before
-returning it. When provisioning production keys, the EEK must be signed by an
-approved authority whose public key is embedded in KeyMint. When certifying test
-keys, KeyMint will accept any EEK without checking the signature, but will
-encrypt and return a test BCC, rather than the real one. The result is that
-only an entity in possession of an Trusted EEK (TEEK) private key can discover
-the plaintext of the production BCC.
-1. Having thus limited access to the public keys to the trusted party only, we
-need to prevent the entity from abusing this unique device identifier. The
-approach and mechanisms for doing that are beyond the scope of this document
-(they must be addressed in the server design), but generally involve taking care
-to ensure that we do not create any links between user IDs, IP addresses or
-issued certificates and the device pubkey.
-
-Although the details of the mechanisms for preventing the entity from abusing
-the BCC are, as stated, beyond the scope of this document, there is a subtle
-design decision here made specifically to enable abuse prevention. Specifically
-the `CertificateRequest` message sent to the server is (in
-[CDDL](https://tools.ietf.org/html/rfc8610)):
-
-```
-cddl
-CertificateRequest = [
- DeviceInfo,
- challenge : bstr,
- ProtectedData,
- MacedKeysToSign
-]
-```
-
-The public keys to be attested by the server are in `MacedKeysToSign`, which is
-a COSE\_Mac0 structure, MACed with a key that is found in `ProtectedData`. The
-MAC key is signed by DK\_pub.
-
-This structure allows the backend component that has access to EEK\_priv to
-decrypt `ProtectedData`, validate that the request is from an authorized device,
-check that the request is fresh and verify and extract the MAC key. That backend
-component never sees any data related to the keys to be signed, but can provide
-the MAC key to another backend component that can verify `MacedKeysToSign` and
-proceed to generate the certificates.
-
-In this way, we can partition the provisioning server into one component that
-knows the device identity, as represented by DK\_pub, but never sees the keys to
-be certified or certificates generated, and another component that sees the keys
-to be certified and certificates generated but does not know the device
-identity.
+Because the UDS, CDIs and derived values are unique, immutable, unspoofable
+hardware-bound identifiers for the device, we must limit access to them. We
+require that the values are never exposed in public APIs and are only available
+to the minimum set of system components that require access to them to function
+correctly.
### Key and cryptographic message formatting
@@ -195,24 +122,6 @@
choice for algorithm implies the implementor should also choose the P256 public
key group further down in the COSE structure.
-### Testability
-
-It's critical that the remote provisioning implementation be testable, to
-minimize the probability that broken devices are sold to end users. To support
-testing, the remote provisioning HAL methods take a `testMode` argument. Keys
-created in test mode are tagged to indicate this. The provisioning server will
-check for the test mode tag and issue test certificates that do not chain back
-to a trusted public key. In test mode, any EEK will be accepted, enabling
-testing tools to use EEKs for which they have the private key so they can
-validate the content of certificate requests. The BCC included in the
-`CertificateRequest` must contain freshly-generated keys, not the real BCC keys.
-
-Keystore (or similar) will need to be able to handle both testMode keys and
-production keys and keep them distinct, generating test certificate requests
-when asked with a test EEK and production certificate requests when asked with a
-production EEK. Likewise, the interface used to instruct Keystore to create keys
-will need to be able to specify whether test or production keys are desired.
-
## Design
### Certificate provisioning flow
@@ -220,25 +129,20 @@
TODO(jbires): Replace this with a `.png` containing a sequence diagram. The
provisioning flow looks something like this:
-Provisioner -> Keystore: Prepare N keys
-Keystore -> KeyMint: generateKeyPair
-KeyMint -> KeyMint: Generate key pair
-KeyMint --> Keystore: key\_blob,pubkey
-Keystore -> Keystore: Store key\_blob,pubkey
-Provisioner -> Server: Get TEEK
-Server --> Provisioner: TEEK
-Provisioner -> Keystore: genCertReq(N, TEEK)
-Keystore -> KeyMint: genCertReq(pubkeys, TEEK)
-KeyMint -> KeyMint: Sign pubkeys & encrypt BCC
-KeyMint --> Keystore: signature, encrypted BCC
-Keystore -> Keystore: Construct cert\_request
-Keystore --> Provisioner: cert\_request
-Provisioner --> Server: cert\_request
-Server -> Server: Validate cert\_request
+rkpd -> KeyMint: generateKeyPair
+KeyMint -> KeyMint: Generate key pair
+KeyMint --> rkpd: key\_blob,pubkey
+rkpd -> rkpd: Store key\_blob,pubkey
+rkpd -> Server: Get challenge
+Server --> rkpd: challenge
+rkpd -> KeyMint: genCertReq(pubkeys, challenge)
+KeyMint -> KeyMint: Sign CSR
+KeyMint --> rkpd: signed CSR
+rkpd --> Server: CSR
+Server -> Server: Validate CSR
Server -> Server: Generate certificates
-Server --> Provisioner: certificates
-Provisioner -> Keystore: certificates
-Keystore -> Keystore: Store certificates
+Server --> rkpd: certificates
+rkpd -> rkpd: Store certificates
The actors in the above diagram are:
@@ -246,10 +150,12 @@
the uploaded device public keys and is responsible for providing encryption
keys, decrypting and validating requests, and generating certificates in
response to requests.
-* **Provisioner** is an application that is responsible for communicating with
- the server and all of the system components that require key certificates
- from the server. It also implements the policy that defines how many key
- pairs each client should keep in their pool.
+* **rkpd** is, optionally, a modular system component that is responsible for
+ communicating with the server and all of the system components that require
+ key certificates from the server. It also implements the policy that defines
+ how many key pairs each client should keep in their pool. When a system
+ ships with rkpd as a modular component, it may be updated independently from
+ the rest of the system.
* **Keystore** is the [Android keystore
daemon](https://developer.android.com/training/articles/keystore) (or, more
generally, whatever system component manages communications with a
@@ -257,51 +163,37 @@
* **KeyMint** is the secure area component that manages cryptographic keys and
performs attestations (or perhaps some other secure area component).
-### `BCC`
+### Android Profile for DICE
-The _Boot Certificate Chain_ (BCC) is the chain of certificates that contains
-DK\_pub as well as other often device-unique certificates. The BCC is
-represented as a COSE\_Key containing DK\_pub followed by an array of
-COSE\_Sign1 "certificates" containing public keys and optional additional
-information, ordered from root to leaf, with each certificate signing the next.
-The first certificate in the array is signed by DK\_pub, the last certificate
-has the KeyMint (or whatever) signing key's public key, KM\_pub. In phase 1
-there is only one entry; DK\_pub and KM\_pub are the same key and the
-certificate is self-signed.
+The Android Profile for DICE is based on the [Open Profile for
+DICE](https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md),
+with additional constraints for details that the Open Profile for DICE leaves
+intentionally underspecified. This section describes the differences from the
+Open Profile for DICE.
-Each COSE\_Sign1 certificate is a CBOR Web Token (CWT) as described in [RFC
-8392](https://tools.ietf.org/html/rfc8392) with additional fields as described
-in the Open Profile for DICE. Of these additional fields, only the
-_subjectPublicKey_ and _keyUsage_ fields are expected to be present for the
-KM\_pub entry (that is, the last entry) in a BCC, but all fields required by the
-Open Profile for DICE are expected for other entries (each of which corresponds
-to a particular firmware component or boot stage). The CWT fields _iss_ and
-_sub_ identify the issuer and subject of the certificate and are consistent
-along the BCC entries; the issuer of a given entry matches the subject of the
-previous entry.
+#### Algorithms
-The BCC is designed to be constructed using the Open Profile for DICE. In this
-case the DK key pair is derived from the UDS as described by that profile and
-all BCC entries before the leaf are CBOR CDI certificates chained from DK\_pub.
-The KM key pair is not part of the derived DICE chain. It is generated (not
-derived) by the KeyMint module, certified by the last key in the DICE chain, and
-added as the leaf BCC entry. The key usage field in this leaf certificate must
-indicate the key is not used to sign certificates. If a UDS certificate is
-available on the device it should appear in the certificate request as the leaf
-of a DKCertChain in AdditionalDKSignatures (see
-[CertificateRequest](#certificaterequest)).
+The choice of algorithm must remain consistent with a given certificate e.g. if
+SHA-256 is used for the code hash then the authority hash, config hash, etc.
+must also use SHA-256.
+
+* UDS and CDI key pairs:
+ * Ed25519 / P-256 / P-384
+* Hash algorithms (digests can be encoded with their natural size and do not
+ need to be the 64-bytes specified by the Open Profile for DICE):
+ * SHA-256 / SHA-384 / SHA-512
+* HKDF with a supported message digest for all key derivation
#### Mode
-The Open Profile for DICE specifies four possible modes with the most important
-mode being `normal`. A certificate must only set the mode to `normal` when all
-of the following conditions are met when loading and verifying the software
-component that is being described by the certificate:
+A certificate must only set the mode to `normal` when all of the following
+conditions are met when loading and verifying the software component that is
+being described by the certificate:
-* verified boot with anti-rollback protection is enabled
-* only the verified boot authorities for production images are enabled
-* debug ports, fuses or other debug facilities are disabled
-* device booted software from the normal primary source e.g. internal flash
+* verified boot with anti-rollback protection is enabled
+* only the verified boot authorities for production images are enabled
+* debug ports, fuses, or other debug facilities are disabled
+* device booted software from the normal primary source e.g. internal flash
The mode should never be `not configured`.
@@ -310,11 +202,11 @@
#### Configuration descriptor
-The Open Profile for DICE allows for an arbitrary configuration descriptor. For
-BCC entries, this configuration descriptor is a CBOR map with the following
-optional fields. If no fields are relevant, an empty map should be encoded.
-Additional implementation-specific fields may be added using key values not in
-the range \[-70000, -70999\] (these are reserved for future additions here).
+The configuration descriptor is a CBOR map with the following optional fields.
+If no fields are relevant, an empty map should be encoded. The key value range
+\[-70000, -70999\] is reserved for the Android Profile for DICE.
+Implementation-specific fields may be added using key values outside of the
+reserved range.
```
| Name | Key | Value type | Meaning |
@@ -332,42 +224,6 @@
: : : : version :
```
-Please see
-[ProtectedData.aidl](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl)
-for a full CDDL definition of the BCC.
-
-### `CertificateRequest`
-
-The full CBOR message that will be sent to the server to request certificates
-is:
-
-```cddl
-CertificateRequest = [
- DeviceInfo,
- challenge : bstr, // Provided by the server
- ProtectedData, // See ProtectedData.aidl
- MacedKeysToSign // See IRemotelyProvisionedComponent.aidl
-]
-
-DeviceInfo = [
- VerifiedDeviceInfo, // See DeviceInfo.aidl
- UnverifiedDeviceInfo
-]
-
-// Unverified info is anything provided by the HLOS. Subject to change out of
-// step with the HAL.
-UnverifiedDeviceInfo = {
- ? "fingerprint" : tstr,
-}
-
-```
-
-It will be the responsibility of Keystore and the Provisioner to construct the
-`CertificateRequest`. The HAL provides a method to generate the elements that
-need to be constructed on the secure side, which are the tag field of
-`MacedKeysToSign`, `VerifiedDeviceInfo`, and the ciphertext field of
-`ProtectedData`.
-
### HAL
The remote provisioning HAL provides a simple interface that can be implemented
diff --git a/threadnetwork/OWNERS b/threadnetwork/OWNERS
new file mode 100644
index 0000000..54fd66d
--- /dev/null
+++ b/threadnetwork/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1288834
+
+include platform/packages/modules/ThreadNetwork:/OWNERS
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
index 9f0f30d..0a645fc 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -379,7 +379,7 @@
break;
}
case FrontendStatusTypeExt1_1::UEC: {
- ASSERT_TRUE(realStatuses[i].uec() == expectStatuses[i].uec());
+ ASSERT_TRUE(realStatuses[i].uec() >= 0 );
break;
}
case FrontendStatusTypeExt1_1::T2_SYSTEM_ID: {
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
index 669fa11..dcdc673 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
@@ -86,7 +86,7 @@
types.push_back(FrontendStatusTypeExt1_1::IS_MISO);
vector<FrontendStatusExt1_1> statuses;
FrontendStatusExt1_1 status;
- status.uec(4);
+ status.uec(0);
statuses.push_back(status);
status.isMiso(true);
statuses.push_back(status);
diff --git a/wifi/1.6/vts/functional/Android.bp b/wifi/1.6/vts/functional/Android.bp
index 2d126c7..92e6d13 100644
--- a/wifi/1.6/vts/functional/Android.bp
+++ b/wifi/1.6/vts/functional/Android.bp
@@ -23,6 +23,28 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+cc_library_static {
+ name: "VtsHalWifiV1_6TargetTestUtil",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "wifi_hidl_test_utils_1_6.cpp",
+ ],
+ export_include_dirs: [
+ ".",
+ ],
+ shared_libs: [
+ "libnativehelper",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.5",
+ "android.hardware.wifi@1.6",
+ "libwifi-system-iface",
+ ],
+}
+
cc_test {
name: "VtsHalWifiV1_6TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
diff --git a/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.cpp b/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.cpp
new file mode 100644
index 0000000..5b8115b
--- /dev/null
+++ b/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#include <VtsHalHidlTargetCallbackBase.h>
+
+#undef NAN // NAN is defined in bionic/libc/include/math.h:38
+
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+#include <android/hardware/wifi/1.6/IWifiChip.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_5::IWifiApIface;
+using ::android::hardware::wifi::V1_6::IfaceConcurrencyType;
+using ::android::hardware::wifi::V1_6::IWifiChip;
+
+namespace {
+
+bool findAnyModeSupportingConcurrencyType(IfaceConcurrencyType desired_type,
+ const std::vector<IWifiChip::ChipMode>& modes,
+ ChipModeId* mode_id) {
+ for (const auto& mode : modes) {
+ for (const auto& combination : mode.availableCombinations) {
+ for (const auto& iface_limit : combination.limits) {
+ const auto& iface_types = iface_limit.types;
+ if (std::find(iface_types.begin(), iface_types.end(), desired_type) !=
+ iface_types.end()) {
+ *mode_id = mode.id;
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+bool configureChipToSupportConcurrencyType(const sp<IWifiChip>& wifi_chip,
+ IfaceConcurrencyType type,
+ ChipModeId* configured_mode_id) {
+ const auto& status_and_modes = HIDL_INVOKE(wifi_chip, getAvailableModes_1_6);
+ if (status_and_modes.first.code != WifiStatusCode::SUCCESS) {
+ return false;
+ }
+ if (!findAnyModeSupportingConcurrencyType(type, status_and_modes.second, configured_mode_id)) {
+ return false;
+ }
+ if (HIDL_INVOKE(wifi_chip, configureChip, *configured_mode_id).code !=
+ WifiStatusCode::SUCCESS) {
+ return false;
+ }
+ return true;
+}
+
+sp<IWifiChip> getWifiChip_1_6(const std::string& instance_name) {
+ return IWifiChip::castFrom(getWifiChip(instance_name));
+}
+
+} // namespace
+
+sp<IWifiApIface> getBridgedWifiApIface_1_6(const std::string& instance_name) {
+ ChipModeId mode_id;
+ sp<IWifiChip> wifi_chip = getWifiChip_1_6(instance_name);
+ if (!wifi_chip.get()) return nullptr;
+ configureChipToSupportConcurrencyType(wifi_chip, IfaceConcurrencyType::AP_BRIDGED, &mode_id);
+ const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createBridgedApIface);
+ return IWifiApIface::castFrom(status_and_iface.second);
+}
diff --git a/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.h b/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.h
new file mode 100644
index 0000000..ab8ff3b
--- /dev/null
+++ b/wifi/1.6/vts/functional/wifi_hidl_test_utils_1_6.h
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+#include <android/hardware/wifi/1.6/IWifiChip.h>
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+
+android::sp<android::hardware::wifi::V1_5::IWifiApIface> getBridgedWifiApIface_1_6(
+ const std::string& instance_name);
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index e61d397..a24bcc0 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -23,6 +23,7 @@
"android.hardware.wifi.hostapd-V1-ndk",
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
+ "VtsHalWifiV1_6TargetTestUtil",
"VtsHalWifiHostapdV1_0TargetTestUtil",
"android.hardware.wifi.hostapd@1.0",
"android.hardware.wifi.hostapd@1.1",
@@ -34,6 +35,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi@1.6",
],
test_suites: [
"general-tests",
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index bd2649f..1b9c0b0 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -29,6 +29,7 @@
#include <hostapd_hidl_test_utils.h>
#include <wifi_hidl_test_utils.h>
#include <wifi_hidl_test_utils_1_5.h>
+#include <wifi_hidl_test_utils_1_6.h>
using aidl::android::hardware::wifi::hostapd::BandMask;
using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
@@ -101,7 +102,7 @@
std::string setupApIfaceAndGetName(bool isBridged) {
android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
if (isBridged) {
- wifi_ap_iface = getBridgedWifiApIface_1_5(wifiInstanceName);
+ wifi_ap_iface = getBridgedWifiApIface_1_6(wifiInstanceName);
} else {
wifi_ap_iface = getWifiApIface_1_5(wifiInstanceName);
}