Merge "Align KeyMint AIDL with usage"
diff --git a/atrace/1.0/default/AtraceDevice.cpp b/atrace/1.0/default/AtraceDevice.cpp
index 4e82b0a..9f0c4c4 100644
--- a/atrace/1.0/default/AtraceDevice.cpp
+++ b/atrace/1.0/default/AtraceDevice.cpp
@@ -16,6 +16,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
#include "AtraceDevice.h"
@@ -39,15 +40,11 @@
// gfx
{
"gfx",
- {"Graphics",
- {{"/sys/kernel/debug/tracing/events/mdss/enable", false},
- {"/sys/kernel/debug/tracing/events/sde/enable", false},
- {"/sys/kernel/debug/tracing/events/mali_systrace/enable", false}}},
+ {"Graphics", {{"mdss", false}, {"sde", false}, {"mali_systrace", false}}},
},
{
"ion",
- {"ION allocation",
- {{"/sys/kernel/debug/tracing/events/kmem/ion_alloc_buffer_start/enable", false}}},
+ {"ION allocation", {{"kmem/ion_alloc_buffer_start", false}}},
},
};
@@ -65,16 +62,31 @@
return Void();
}
+AtraceDevice::AtraceDevice() {
+ struct stat st;
+
+ tracefs_event_root_ = "/sys/kernel/tracing/events/";
+ if (stat(tracefs_event_root_.c_str(), &st) != 0) {
+ tracefs_event_root_ = "/sys/kernel/debug/tracing/events/";
+ CHECK(stat(tracefs_event_root_.c_str(), &st) == 0) << "tracefs must be mounted at either"
+ "/sys/kernel/tracing or "
+ "/sys/kernel/debug/tracing";
+ }
+}
+
Return<::android::hardware::atrace::V1_0::Status> AtraceDevice::enableCategories(
- const hidl_vec<hidl_string>& categories) {
+ const hidl_vec<hidl_string>& categories) {
if (!categories.size()) {
return Status::ERROR_INVALID_ARGUMENT;
}
+
for (auto& c : categories) {
if (kTracingMap.count(c)) {
for (auto& p : kTracingMap.at(c).paths) {
- if (!android::base::WriteStringToFile("1", p.first)) {
- LOG(ERROR) << "Failed to enable tracing on: " << p.first;
+ std::string tracefs_event_enable_path = android::base::StringPrintf(
+ "%s%s/enable", tracefs_event_root_.c_str(), p.first.c_str());
+ if (!android::base::WriteStringToFile("1", tracefs_event_enable_path)) {
+ LOG(ERROR) << "Failed to enable tracing on: " << tracefs_event_enable_path;
if (p.second) {
// disable before return
disableAllCategories();
@@ -91,10 +103,13 @@
Return<::android::hardware::atrace::V1_0::Status> AtraceDevice::disableAllCategories() {
auto ret = Status::SUCCESS;
+
for (auto& c : kTracingMap) {
for (auto& p : c.second.paths) {
- if (!android::base::WriteStringToFile("0", p.first)) {
- LOG(ERROR) << "Failed to disable tracing on: " << p.first;
+ std::string tracefs_event_enable_path = android::base::StringPrintf(
+ "%s%s/enable", tracefs_event_root_.c_str(), p.first.c_str());
+ if (!android::base::WriteStringToFile("0", tracefs_event_enable_path)) {
+ LOG(ERROR) << "Failed to disable tracing on: " << tracefs_event_enable_path;
if (p.second) {
ret = Status::ERROR_TRACING_POINT;
}
diff --git a/atrace/1.0/default/AtraceDevice.h b/atrace/1.0/default/AtraceDevice.h
index e700f89..ab87c65 100644
--- a/atrace/1.0/default/AtraceDevice.h
+++ b/atrace/1.0/default/AtraceDevice.h
@@ -36,12 +36,16 @@
using ::android::hardware::Void;
struct AtraceDevice : public IAtraceDevice {
+ AtraceDevice();
// Methods from ::android::hardware::atrace::V1_0::IAtraceDevice follow.
Return<void> listCategories(listCategories_cb _hidl_cb) override;
Return<::android::hardware::atrace::V1_0::Status> enableCategories(
const hidl_vec<hidl_string>& categories) override;
Return<::android::hardware::atrace::V1_0::Status> disableAllCategories() override;
+ private:
+ std::string tracefs_event_root_;
+
// Methods from ::android::hidl::base::V1_0::IBase follow.
};
diff --git a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
index eb54c39..7110b45 100644
--- a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
+++ b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
@@ -1,10 +1,14 @@
on late-init
# vendor graphics trace points
chmod 0666 /sys/kernel/debug/tracing/events/sde/enable
+ chmod 0666 /sys/kernel/tracing/events/sde/enable
chmod 0666 /sys/kernel/debug/tracing/events/mdss/enable
+ chmod 0666 /sys/kernel/tracing/events/mdss/enable
chmod 0666 /sys/kernel/debug/tracing/events/mali_systrace/enable
+ chmod 0666 /sys/kernel/tracing/events/mali_systrace/enable
# ion allocation trace point
chmod 0666 /sys/kernel/debug/tracing/events/kmem/ion_alloc_buffer_start/enable
+ chmod 0666 /sys/kernel/tracing/events/kmem/ion_alloc_buffer_start/enable
service vendor.atrace-hal-1-0 /vendor/bin/hw/android.hardware.atrace@1.0-service
interface android.hardware.atrace@1.0::IAtraceDevice default
diff --git a/bluetooth/1.0/vts/functional/Android.bp b/bluetooth/1.0/vts/functional/Android.bp
index 4806fef..768142c 100644
--- a/bluetooth/1.0/vts/functional/Android.bp
+++ b/bluetooth/1.0/vts/functional/Android.bp
@@ -31,6 +31,7 @@
"android.hardware.bluetooth@1.0",
"libbluetooth-types",
],
+ test_config: "VtsHalBluetoothV1_0TargetTest.xml",
test_suites: [
"general-tests",
"vts",
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.xml b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.xml
new file mode 100644
index 0000000..09463c9
--- /dev/null
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalBluetoothV1_0TargetTest.">
+ <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.StopServicesSetup">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <option name="bluetooth" value="off" />
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalBluetoothV1_0TargetTest->/data/local/tmp/VtsHalBluetoothV1_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalBluetoothV1_0TargetTest" />
+ </test>
+</configuration>
diff --git a/bluetooth/1.1/vts/functional/Android.bp b/bluetooth/1.1/vts/functional/Android.bp
index e64d5a9..7f56647 100644
--- a/bluetooth/1.1/vts/functional/Android.bp
+++ b/bluetooth/1.1/vts/functional/Android.bp
@@ -32,5 +32,6 @@
"android.hardware.bluetooth@1.0",
"libbluetooth-types",
],
+ test_config: "VtsHalBluetoothV1_1TargetTest.xml",
test_suites: ["general-tests", "vts"],
}
diff --git a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml
new file mode 100644
index 0000000..d64751a
--- /dev/null
+++ b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalBluetoothV1_1TargetTest.">
+ <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.DeviceSetup">
+ <option name="bluetooth" value="off" />
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalBluetoothV1_1TargetTest->/data/local/tmp/VtsHalBluetoothV1_1TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalBluetoothV1_1TargetTest" />
+ </test>
+</configuration>
diff --git a/current.txt b/current.txt
index 454d43e..f446754 100644
--- a/current.txt
+++ b/current.txt
@@ -776,8 +776,8 @@
dabe23dde7c9e3ad65c61def7392f186d7efe7f4216f9b6f9cf0863745b1a9f4 android.hardware.keymaster@4.1::IKeymasterDevice
cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice
f729ee6a5f136b25d79ea6895d24700fce413df555baaecf2c39e4440d15d043 android.hardware.neuralnetworks@1.0::types
-a84f8dac7a9b75de1cc2936a9b429b9b62b32a31ea88ca52c29f98f5ddc0fa95 android.hardware.neuralnetworks@1.2::types
-cd331b92312d16ab89f475c39296abbf539efc4114a8c5c2b136ad99b904ef33 android.hardware.neuralnetworks@1.3::types
+38c1a3eb5c3dfa4cc40b7cf4be0e9850440e2c57197fba7407081679b358aa22 android.hardware.neuralnetworks@1.2::types
+550619f876cadbea1f718edce120f0e1dd4a6f4bd4c28b59d479677dc86b0aec android.hardware.neuralnetworks@1.3::types
c3fec5bd470984402997f78a74b6511efc4063b270f2bd9ee7b78f48b683a1bb android.hardware.neuralnetworks@1.3::IDevice
0fdfad62c2ec33b52e6687004e5a1971c02d10b93ee4d26df5ccff7ce032494a android.hardware.neuralnetworks@1.3::IPreparedModel
e8c86c69c438da8d1549856c1bb3e2d1b8da52722f8235ff49a30f2cce91742c android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index 50f282f..46f95dd 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -73,10 +73,15 @@
IComposerClient::Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
+ void setDimensions(int32_t displayWidth, int32_t displayHeight) {
+ mDisplayWidth = displayWidth;
+ mDisplayHeight = displayHeight;
+ }
+
private:
const Display mDisplay;
- const int32_t mDisplayWidth;
- const int32_t mDisplayHeight;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
};
class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
@@ -194,6 +199,31 @@
const std::vector<ContentType>& capabilities,
const ContentType& contentType, const char* contentTypeStr);
+ Error setActiveConfigWithConstraints(
+ VtsDisplay& display, Config config,
+ const IComposerClient::VsyncPeriodChangeConstraints& constraints,
+ VsyncPeriodChangeTimeline* timeline) {
+ const auto error = mComposerClient->setActiveConfigWithConstraints(display.get(), config,
+ constraints, timeline);
+ if (error == Error::NONE) {
+ const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), config, IComposerClient::Attribute::WIDTH);
+ const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), config, IComposerClient::Attribute::HEIGHT);
+ display.setDimensions(displayWidth, displayHeight);
+ }
+ return error;
+ }
+
+ void setActiveConfig(VtsDisplay& display, Config config) {
+ mComposerClient->setActiveConfig(display.get(), config);
+ const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), config, IComposerClient::Attribute::WIDTH);
+ const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), config, IComposerClient::Attribute::HEIGHT);
+ display.setDimensions(displayWidth, displayHeight);
+ }
+
private:
// use the slot count usually set by SF
static constexpr uint32_t kBufferSlotCount = 64;
@@ -347,7 +377,7 @@
}
TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) {
- for (const auto& display : mDisplays) {
+ for (VtsDisplay& display : mDisplays) {
for (Config config : mComposerClient->getDisplayConfigs(display.get())) {
VsyncPeriodNanos expectedVsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
display.get(), config,
@@ -358,8 +388,8 @@
constraints.desiredTimeNanos = systemTime();
constraints.seamlessRequired = false;
- EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
- display.get(), config, constraints, &timeline));
+ EXPECT_EQ(Error::NONE,
+ setActiveConfigWithConstraints(display, config, constraints, &timeline));
if (timeline.refreshRequired) {
sendRefreshFrame(display, &timeline);
@@ -411,11 +441,10 @@
constraints.seamlessRequired = false;
constraints.desiredTimeNanos = systemTime();
- for (const auto& display : mDisplays) {
+ for (VtsDisplay& display : mDisplays) {
Config invalidConfigId = GetInvalidConfigId(display.get());
EXPECT_EQ(Error::BAD_CONFIG,
- mComposerClient->setActiveConfigWithConstraints(display.get(), invalidConfigId,
- constraints, &timeline));
+ setActiveConfigWithConstraints(display, invalidConfigId, constraints, &timeline));
}
}
@@ -426,7 +455,7 @@
constraints.seamlessRequired = true;
constraints.desiredTimeNanos = systemTime();
- for (const auto& display : mDisplays) {
+ for (VtsDisplay& display : mDisplays) {
forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
const auto configGroup1 = mComposerClient->getDisplayAttribute_2_4(
display.get(), config1,
@@ -435,11 +464,10 @@
display.get(), config2,
IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
if (configGroup1 != configGroup2) {
- mComposerClient->setActiveConfig(display.get(), config1);
+ setActiveConfig(display, config1);
sendRefreshFrame(display, nullptr);
EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED,
- mComposerClient->setActiveConfigWithConstraints(display.get(), config2,
- constraints, &timeline));
+ setActiveConfigWithConstraints(display, config2, constraints, &timeline));
}
});
}
@@ -502,6 +530,8 @@
mWriter->presentDisplay();
execute();
+
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(display.get(), layer));
}
void GraphicsComposerHidlTest::waitForVsyncPeriodChange(Display display,
@@ -523,9 +553,9 @@
}
void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestParameters& params) {
- for (const auto& display : mDisplays) {
+ for (VtsDisplay& display : mDisplays) {
forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
- mComposerClient->setActiveConfig(display.get(), config1);
+ setActiveConfig(display, config1);
sendRefreshFrame(display, nullptr);
int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4(
@@ -543,8 +573,8 @@
IComposerClient::VsyncPeriodChangeConstraints constraints = {
.desiredTimeNanos = systemTime() + params.delayForChange,
.seamlessRequired = false};
- EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
- display.get(), config2, constraints, &timeline));
+ EXPECT_EQ(Error::NONE,
+ setActiveConfigWithConstraints(display, config2, constraints, &timeline));
EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
// Refresh rate should change within a reasonable time
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h
index 4681b9e..db3b2ad 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h
@@ -52,7 +52,6 @@
const std::string& getVersionString() const override;
nn::Version getFeatureLevel() const override;
nn::DeviceType getType() const override;
- bool isUpdatable() const override;
const std::vector<nn::Extension>& getSupportedExtensions() const override;
const nn::Capabilities& getCapabilities() const override;
std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp
index bb31a26..93bd81a 100644
--- a/neuralnetworks/1.0/utils/src/Device.cpp
+++ b/neuralnetworks/1.0/utils/src/Device.cpp
@@ -106,10 +106,6 @@
return nn::DeviceType::OTHER;
}
-bool Device::isUpdatable() const {
- return false;
-}
-
const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
return kExtensions;
}
diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h
index 3aec8ee..5e224b5 100644
--- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h
+++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h
@@ -52,7 +52,6 @@
const std::string& getVersionString() const override;
nn::Version getFeatureLevel() const override;
nn::DeviceType getType() const override;
- bool isUpdatable() const override;
const std::vector<nn::Extension>& getSupportedExtensions() const override;
const nn::Capabilities& getCapabilities() const override;
std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp
index d2ef57f..3197ef4 100644
--- a/neuralnetworks/1.1/utils/src/Device.cpp
+++ b/neuralnetworks/1.1/utils/src/Device.cpp
@@ -106,10 +106,6 @@
return nn::DeviceType::UNKNOWN;
}
-bool Device::isUpdatable() const {
- return false;
-}
-
const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
return kExtensions;
}
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 03aed86..f5b6ead 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -3618,7 +3618,7 @@
* front of dimension i.
* padding[i, 1] specifies the number of elements to be padded after
* the end of dimension i.
- * * 2: An scalar specifying the value to use for padding input0.
+ * * 2: A scalar specifying the value to use for padding input0.
* For input tensor of {@link OperandType::TENSOR_FLOAT16}, the
* pad value must be of {@link OperandType::FLOAT16}.
* For input tensor of {@link OperandType::TENSOR_FLOAT32}, the
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
index 489f857..b4bef5e 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
@@ -71,7 +71,6 @@
const std::string& getVersionString() const override;
nn::Version getFeatureLevel() const override;
nn::DeviceType getType() const override;
- bool isUpdatable() const override;
const std::vector<nn::Extension>& getSupportedExtensions() const override;
const nn::Capabilities& getCapabilities() const override;
std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp
index 1954dfa..9fe0de2 100644
--- a/neuralnetworks/1.2/utils/src/Device.cpp
+++ b/neuralnetworks/1.2/utils/src/Device.cpp
@@ -199,10 +199,6 @@
return kDeviceType;
}
-bool Device::isUpdatable() const {
- return false;
-}
-
const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
return kExtensions;
}
diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal
index a5dbd5e..a26b858 100644
--- a/neuralnetworks/1.3/types.hal
+++ b/neuralnetworks/1.3/types.hal
@@ -3834,7 +3834,7 @@
* front of dimension i.
* padding[i, 1] specifies the number of elements to be padded after
* the end of dimension i.
- * * 2: An scalar specifying the value to use for padding input0.
+ * * 2: A scalar specifying the value to use for padding input0.
* For input tensor of {@link OperandType::TENSOR_FLOAT16}, the
* pad value must be of {@link OperandType::FLOAT16}.
* For input tensor of {@link OperandType::TENSOR_FLOAT32}, the
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h
index f36b6c0..84f606a 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h
@@ -54,7 +54,6 @@
const std::string& getVersionString() const override;
nn::Version getFeatureLevel() const override;
nn::DeviceType getType() const override;
- bool isUpdatable() const override;
const std::vector<nn::Extension>& getSupportedExtensions() const override;
const nn::Capabilities& getCapabilities() const override;
std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp
index 87c9f32..d710b85 100644
--- a/neuralnetworks/1.3/utils/src/Device.cpp
+++ b/neuralnetworks/1.3/utils/src/Device.cpp
@@ -150,10 +150,6 @@
return kDeviceType;
}
-bool Device::isUpdatable() const {
- return false;
-}
-
const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
return kExtensions;
}
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
index 3f49154..e7fb90d 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
@@ -3693,7 +3693,7 @@
* front of dimension i.
* padding[i, 1] specifies the number of elements to be padded after
* the end of dimension i.
- * * 2: An scalar specifying the value to use for padding input0.
+ * * 2: A scalar specifying the value to use for padding input0.
* For input tensor of {@link OperandType::TENSOR_FLOAT16}, the
* pad value must be of {@link OperandType::FLOAT16}.
* For input tensor of {@link OperandType::TENSOR_FLOAT32}, the
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Device.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Device.h
index eb194e3..1457646 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Device.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Device.h
@@ -54,7 +54,6 @@
const std::string& getVersionString() const override;
nn::Version getFeatureLevel() const override;
nn::DeviceType getType() const override;
- bool isUpdatable() const override;
const std::vector<nn::Extension>& getSupportedExtensions() const override;
const nn::Capabilities& getCapabilities() const override;
std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp
index 02ca861..0fd453b 100644
--- a/neuralnetworks/aidl/utils/src/Device.cpp
+++ b/neuralnetworks/aidl/utils/src/Device.cpp
@@ -178,10 +178,6 @@
return kDeviceType;
}
-bool Device::isUpdatable() const {
- return false;
-}
-
const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
return kExtensions;
}
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
index d843526..5e62b9a 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
@@ -32,7 +32,7 @@
class InvalidDevice final : public nn::IDevice {
public:
InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel,
- nn::DeviceType type, bool isUpdatable, std::vector<nn::Extension> extensions,
+ nn::DeviceType type, std::vector<nn::Extension> extensions,
nn::Capabilities capabilities,
std::pair<uint32_t, uint32_t> numberOfCacheFilesNeeded);
@@ -40,7 +40,6 @@
const std::string& getVersionString() const override;
nn::Version getFeatureLevel() const override;
nn::DeviceType getType() const override;
- bool isUpdatable() const override;
const std::vector<nn::Extension>& getSupportedExtensions() const override;
const nn::Capabilities& getCapabilities() const override;
std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
@@ -71,7 +70,6 @@
const std::string kVersionString;
const nn::Version kFeatureLevel;
const nn::DeviceType kType;
- const bool kIsUpdatable;
const std::vector<nn::Extension> kExtensions;
const nn::Capabilities kCapabilities;
const std::pair<uint32_t, uint32_t> kNumberOfCacheFilesNeeded;
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
index 8199c52..84ae799 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
@@ -53,7 +53,6 @@
const std::string& getVersionString() const override;
nn::Version getFeatureLevel() const override;
nn::DeviceType getType() const override;
- bool isUpdatable() const override;
const std::vector<nn::Extension>& getSupportedExtensions() const override;
const nn::Capabilities& getCapabilities() const override;
std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/utils/common/src/InvalidDevice.cpp b/neuralnetworks/utils/common/src/InvalidDevice.cpp
index 81bca7f..535ccb4 100644
--- a/neuralnetworks/utils/common/src/InvalidDevice.cpp
+++ b/neuralnetworks/utils/common/src/InvalidDevice.cpp
@@ -32,14 +32,13 @@
namespace android::hardware::neuralnetworks::utils {
InvalidDevice::InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel,
- nn::DeviceType type, bool isUpdatable,
- std::vector<nn::Extension> extensions, nn::Capabilities capabilities,
+ nn::DeviceType type, std::vector<nn::Extension> extensions,
+ nn::Capabilities capabilities,
std::pair<uint32_t, uint32_t> numberOfCacheFilesNeeded)
: kName(std::move(name)),
kVersionString(std::move(versionString)),
kFeatureLevel(featureLevel),
kType(type),
- kIsUpdatable(isUpdatable),
kExtensions(std::move(extensions)),
kCapabilities(std::move(capabilities)),
kNumberOfCacheFilesNeeded(numberOfCacheFilesNeeded) {}
@@ -60,10 +59,6 @@
return kType;
}
-bool InvalidDevice::isUpdatable() const {
- return kIsUpdatable;
-}
-
const std::vector<nn::Extension>& InvalidDevice::getSupportedExtensions() const {
return kExtensions;
}
diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp
index 13965af..2023c9a 100644
--- a/neuralnetworks/utils/common/src/ResilientDevice.cpp
+++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp
@@ -122,14 +122,12 @@
};
if (compare(&IDevice::getName) || compare(&IDevice::getVersionString) ||
compare(&IDevice::getFeatureLevel) || compare(&IDevice::getType) ||
- compare(&IDevice::isUpdatable) || compare(&IDevice::getSupportedExtensions) ||
- compare(&IDevice::getCapabilities)) {
+ compare(&IDevice::getSupportedExtensions) || compare(&IDevice::getCapabilities)) {
LOG(ERROR) << "Recovered device has different metadata than what is cached. Marking "
"IDevice object as invalid.";
device = std::make_shared<const InvalidDevice>(
- kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(),
- mDevice->isUpdatable(), kExtensions, kCapabilities,
- mDevice->getNumberOfCacheFilesNeeded());
+ kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(), kExtensions,
+ kCapabilities, mDevice->getNumberOfCacheFilesNeeded());
mIsValid = false;
}
@@ -153,10 +151,6 @@
return getDevice()->getType();
}
-bool ResilientDevice::isUpdatable() const {
- return getDevice()->isUpdatable();
-}
-
const std::vector<nn::Extension>& ResilientDevice::getSupportedExtensions() const {
return kExtensions;
}
diff --git a/neuralnetworks/utils/common/test/MockDevice.h b/neuralnetworks/utils/common/test/MockDevice.h
index b274716..a9428bc 100644
--- a/neuralnetworks/utils/common/test/MockDevice.h
+++ b/neuralnetworks/utils/common/test/MockDevice.h
@@ -29,7 +29,6 @@
MOCK_METHOD(const std::string&, getVersionString, (), (const, override));
MOCK_METHOD(Version, getFeatureLevel, (), (const, override));
MOCK_METHOD(DeviceType, getType, (), (const, override));
- MOCK_METHOD(bool, isUpdatable, (), (const, override));
MOCK_METHOD(const std::vector<Extension>&, getSupportedExtensions, (), (const, override));
MOCK_METHOD(const Capabilities&, getCapabilities, (), (const, override));
MOCK_METHOD((std::pair<uint32_t, uint32_t>), getNumberOfCacheFilesNeeded, (),
diff --git a/neuralnetworks/utils/service/include/nnapi/hal/Service.h b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
index e339627..2fd5237 100644
--- a/neuralnetworks/utils/service/include/nnapi/hal/Service.h
+++ b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
@@ -22,10 +22,15 @@
#include <memory>
#include <vector>
-namespace android::nn::hal {
+namespace android::hardware::neuralnetworks::service {
-std::vector<nn::SharedDevice> getDevices();
+struct SharedDeviceAndUpdatability {
+ nn::SharedDevice device;
+ bool isDeviceUpdatable = false;
+};
-} // namespace android::nn::hal
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers);
+
+} // namespace android::hardware::neuralnetworks::service
#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_SERVICE_H
diff --git a/neuralnetworks/utils/service/src/Service.cpp b/neuralnetworks/utils/service/src/Service.cpp
index 75ab1f9..2286288 100644
--- a/neuralnetworks/utils/service/src/Service.cpp
+++ b/neuralnetworks/utils/service/src/Service.cpp
@@ -35,6 +35,7 @@
#include <nnapi/hal/1.2/Service.h>
#include <nnapi/hal/1.3/Service.h>
#include <nnapi/hal/aidl/Service.h>
+#include <nnapi/hal/aidl/Utils.h>
#include <functional>
#include <memory>
@@ -50,7 +51,7 @@
using getDeviceFn = std::add_pointer_t<nn::GeneralResult<nn::SharedDevice>(const std::string&)>;
void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
- std::vector<nn::SharedDevice>* devices,
+ std::vector<SharedDeviceAndUpdatability>* devices,
std::unordered_set<std::string>* registeredDevices) {
CHECK(devices != nullptr);
CHECK(registeredDevices != nullptr);
@@ -62,7 +63,7 @@
if (maybeDevice.has_value()) {
auto device = std::move(maybeDevice).value();
CHECK(device != nullptr);
- devices->push_back(std::move(device));
+ devices->push_back({.device = std::move(device)});
} else {
LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
<< ": " << maybeDevice.error().message;
@@ -71,8 +72,9 @@
}
}
-void getAidlDevices(std::vector<nn::SharedDevice>* devices,
- std::unordered_set<std::string>* registeredDevices) {
+void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
+ std::unordered_set<std::string>* registeredDevices,
+ bool includeUpdatableDrivers) {
CHECK(devices != nullptr);
CHECK(registeredDevices != nullptr);
@@ -89,12 +91,21 @@
}
for (const auto& name : names) {
+ bool isDeviceUpdatable = false;
+ if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
+ const auto instance = std::string(aidl_hal::IDevice::descriptor) + '/' + name;
+ isDeviceUpdatable = AServiceManager_isUpdatableViaApex(instance.c_str());
+ }
+ if (isDeviceUpdatable && !includeUpdatableDrivers) {
+ continue;
+ }
if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) {
auto maybeDevice = aidl_hal::utils::getDevice(name);
if (maybeDevice.has_value()) {
auto device = std::move(maybeDevice).value();
CHECK(device != nullptr);
- devices->push_back(std::move(device));
+ devices->push_back(
+ {.device = std::move(device), .isDeviceUpdatable = isDeviceUpdatable});
} else {
LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
<< ": " << maybeDevice.error().message;
@@ -103,11 +114,13 @@
}
}
-std::vector<nn::SharedDevice> getDevices() {
- std::vector<nn::SharedDevice> devices;
+} // namespace
+
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers) {
+ std::vector<SharedDeviceAndUpdatability> devices;
std::unordered_set<std::string> registeredDevices;
- getAidlDevices(&devices, ®isteredDevices);
+ getAidlDevices(&devices, ®isteredDevices, includeUpdatableDrivers);
getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
®isteredDevices);
@@ -121,13 +134,4 @@
return devices;
}
-} // namespace
} // namespace android::hardware::neuralnetworks::service
-
-namespace android::nn::hal {
-
-std::vector<nn::SharedDevice> getDevices() {
- return hardware::neuralnetworks::service::getDevices();
-}
-
-} // namespace android::nn::hal
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index f343707..7c05984 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -433,6 +433,8 @@
::android::hardware::radio::V1_6::RadioError::NONE,
::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
}
+
+ sleep(1);
serial = GetRandomSerialNumber();
res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER,
@@ -453,6 +455,8 @@
::android::hardware::radio::V1_6::RadioError::NONE,
::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
}
+
+ sleep(1);
serial = GetRandomSerialNumber();
res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::HOLD, 60000);
@@ -473,6 +477,8 @@
::android::hardware::radio::V1_6::RadioError::NONE,
::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
}
+
+ sleep(1);
serial = GetRandomSerialNumber();
res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60000);
diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp
index b9fb2a9..1f67a3e 100644
--- a/rebootescrow/aidl/default/Android.bp
+++ b/rebootescrow/aidl/default/Android.bp
@@ -87,7 +87,9 @@
],
static_libs: [
"libhadamardutils",
- "libgtest_prod",
+ ],
+ header_libs: [
+ "libgtest_prod_headers",
],
shared_libs: [
"liblog",
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index daa3e18..4e951d6 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -35,6 +35,12 @@
using AttestKeyTest = KeyMintAidlTestBase;
+/*
+ * AttestKeyTest.AllRsaSizes
+ *
+ * This test creates self signed RSA attestation keys of various sizes, and verify they can be
+ * used to sign other RSA and EC keys.
+ */
TEST_P(AttestKeyTest, AllRsaSizes) {
for (auto size : ValidKeySizes(Algorithm::RSA)) {
/*
@@ -54,7 +60,7 @@
EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)) << "Failed on size " << size;
/*
- * Use attestation key to sign RSA key
+ * Use attestation key to sign RSA signing key
*/
attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
vector<uint8_t> attested_key_blob;
@@ -81,14 +87,47 @@
EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
- if (attest_key_cert_chain.size() > 0) {
- attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
- }
+ attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain));
+ EXPECT_EQ(attested_key_cert_chain.size(), 2);
+
+ /*
+ * Use attestation key to sign RSA decryption key
+ */
+ attested_key_characteristics.resize(0);
+ attested_key_cert_chain.resize(0);
+ EXPECT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaEncryptionKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AttestationChallenge("foo2")
+ .AttestationApplicationId("bar2")
+ .SetDefaultValidity(),
+ attest_key, &attested_key_blob, &attested_key_characteristics,
+ &attested_key_cert_chain));
+
+ CheckedDeleteKey(&attested_key_blob);
+
+ hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+ sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+ EXPECT_TRUE(verify_attestation_record("foo2", "bar2", sw_enforced, hw_enforced, SecLevel(),
+ attested_key_cert_chain[0].encodedCertificate));
+
+ // Attestation by itself is not valid (last entry is not self-signed).
+ EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
+
+ // Appending the attest_key chain to the attested_key_chain should yield a valid chain.
+ attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
+ EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain));
+ EXPECT_EQ(attested_key_cert_chain.size(), 2);
/*
* Use attestation key to sign EC key
*/
+ attested_key_characteristics.resize(0);
+ attested_key_cert_chain.resize(0);
EXPECT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
.EcdsaSigningKey(EcCurve::P_256)
@@ -111,9 +150,7 @@
EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
- if (attest_key_cert_chain.size() > 0) {
- attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
- }
+ attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain));
// Bail early if anything failed.
@@ -121,6 +158,327 @@
}
}
+/*
+ * AttestKeyTest.RsaAttestedAttestKeys
+ *
+ * This test creates an RSA attestation key signed by factory keys, and varifies it can be
+ * used to sign other RSA and EC keys.
+ */
+TEST_P(AttestKeyTest, RsaAttestedAttestKeys) {
+ auto challenge = "hello";
+ auto app_id = "foo";
+
+ auto subject = "cert subj 2";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 66;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
+ /*
+ * Create attestation key.
+ */
+ AttestationKey attest_key;
+ vector<KeyCharacteristics> attest_key_characteristics;
+ vector<Certificate> attest_key_cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .AttestKey()
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ {} /* attestation signing key */, &attest_key.keyBlob,
+ &attest_key_characteristics, &attest_key_cert_chain));
+
+ EXPECT_GT(attest_key_cert_chain.size(), 1);
+ verify_subject_and_serial(attest_key_cert_chain[0], serial_int, subject, false);
+ EXPECT_TRUE(ChainSignaturesAreValid(attest_key_cert_chain));
+
+ AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attest_key_characteristics);
+ AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attest_key_characteristics);
+ EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
+ sw_enforced, hw_enforced, SecLevel(),
+ attest_key_cert_chain[0].encodedCertificate));
+
+ /*
+ * Use attestation key to sign RSA key
+ */
+ attest_key.issuerSubjectName = subject_der;
+ vector<uint8_t> attested_key_blob;
+ vector<KeyCharacteristics> attested_key_characteristics;
+ vector<Certificate> attested_key_cert_chain;
+
+ auto subject2 = "cert subject";
+ vector<uint8_t> subject_der2(make_name_from_str(subject2));
+
+ uint64_t serial_int2 = 987;
+ vector<uint8_t> serial_blob2(build_serial_blob(serial_int2));
+
+ EXPECT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob2)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der2)
+ .SetDefaultValidity(),
+ attest_key, &attested_key_blob, &attested_key_characteristics,
+ &attested_key_cert_chain));
+
+ CheckedDeleteKey(&attested_key_blob);
+ CheckedDeleteKey(&attest_key.keyBlob);
+
+ AuthorizationSet hw_enforced2 = HwEnforcedAuthorizations(attested_key_characteristics);
+ AuthorizationSet sw_enforced2 = SwEnforcedAuthorizations(attested_key_characteristics);
+ EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced2, hw_enforced2, SecLevel(),
+ attested_key_cert_chain[0].encodedCertificate));
+
+ // Attestation by itself is not valid (last entry is not self-signed).
+ EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
+
+ // Appending the attest_key chain to the attested_key_chain should yield a valid chain.
+ attested_key_cert_chain.insert(attested_key_cert_chain.end(), attest_key_cert_chain.begin(),
+ attest_key_cert_chain.end());
+
+ EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain));
+ EXPECT_GT(attested_key_cert_chain.size(), 2);
+ verify_subject_and_serial(attested_key_cert_chain[0], serial_int2, subject2, false);
+}
+
+/*
+ * AttestKeyTest.RsaAttestKeyChaining
+ *
+ * This test creates a chain of multiple RSA attest keys, each used to sign the next attest key,
+ * with the last attest key signed by the factory chain.
+ */
+TEST_P(AttestKeyTest, RsaAttestKeyChaining) {
+ const int chain_size = 6;
+ vector<vector<uint8_t>> key_blob_list(chain_size);
+ vector<vector<Certificate>> cert_chain_list(chain_size);
+
+ for (int i = 0; i < chain_size; i++) {
+ string sub = "attest key chaining ";
+ char index = '1' + i;
+ string subject = sub + index;
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 7000 + i;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
+ vector<KeyCharacteristics> attested_key_characteristics;
+ AttestationKey attest_key;
+ optional<AttestationKey> attest_key_opt;
+
+ if (i > 0) {
+ attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1));
+ attest_key.keyBlob = key_blob_list[i - 1];
+ attest_key_opt = attest_key;
+ }
+
+ EXPECT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .AttestKey()
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
+ &cert_chain_list[i]));
+
+ AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+ AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+ EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+ cert_chain_list[i][0].encodedCertificate));
+
+ if (i > 0) {
+ /*
+ * The first key is attestated with factory chain, but all the rest of the keys are
+ * not supposed to be returned in attestation certificate chains.
+ */
+ EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i]));
+
+ // Appending the attest_key chain to the attested_key_chain should yield a valid chain.
+ cert_chain_list[i].insert(cert_chain_list[i].end(), //
+ cert_chain_list[i - 1].begin(), //
+ cert_chain_list[i - 1].end());
+ }
+
+ EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
+ 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]);
+ }
+}
+
+/*
+ * AttestKeyTest.EcAttestKeyChaining
+ *
+ * This test creates a chain of multiple Ec attest keys, each used to sign the next attest key,
+ * with the last attest key signed by the factory chain.
+ */
+TEST_P(AttestKeyTest, EcAttestKeyChaining) {
+ const int chain_size = 6;
+ vector<vector<uint8_t>> key_blob_list(chain_size);
+ vector<vector<Certificate>> cert_chain_list(chain_size);
+
+ for (int i = 0; i < chain_size; i++) {
+ string sub = "Ec attest key chaining ";
+ char index = '1' + i;
+ string subject = sub + index;
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 800000 + i;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
+ vector<KeyCharacteristics> attested_key_characteristics;
+ AttestationKey attest_key;
+ optional<AttestationKey> attest_key_opt;
+
+ if (i > 0) {
+ attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1));
+ attest_key.keyBlob = key_blob_list[i - 1];
+ attest_key_opt = attest_key;
+ }
+
+ EXPECT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .EcdsaSigningKey(224)
+ .AttestKey()
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
+ &cert_chain_list[i]));
+
+ AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+ AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+ EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+ cert_chain_list[i][0].encodedCertificate));
+
+ if (i > 0) {
+ /*
+ * The first key is attestated with factory chain, but all the rest of the keys are
+ * not supposed to be returned in attestation certificate chains.
+ */
+ EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i]));
+
+ // Appending the attest_key chain to the attested_key_chain should yield a valid chain.
+ cert_chain_list[i].insert(cert_chain_list[i].end(), //
+ cert_chain_list[i - 1].begin(), //
+ cert_chain_list[i - 1].end());
+ }
+
+ EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
+ 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]);
+ }
+}
+
+/*
+ * AttestKeyTest.AlternateAttestKeyChaining
+ *
+ * This test creates a chain of multiple attest keys, in the order Ec - RSA - Ec - RSA ....
+ * Each attest key is used to sign the next attest key, with the last attest key signed by
+ * the factory chain. This is to verify different algorithms of attest keys can
+ * cross sign each other and be chained together.
+ */
+TEST_P(AttestKeyTest, AlternateAttestKeyChaining) {
+ const int chain_size = 6;
+ vector<vector<uint8_t>> key_blob_list(chain_size);
+ vector<vector<Certificate>> cert_chain_list(chain_size);
+
+ for (int i = 0; i < chain_size; i++) {
+ string sub = "Alt attest key chaining ";
+ char index = '1' + i;
+ string subject = sub + index;
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 90000000 + i;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
+ vector<KeyCharacteristics> attested_key_characteristics;
+ AttestationKey attest_key;
+ optional<AttestationKey> attest_key_opt;
+
+ if (i > 0) {
+ attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1));
+ attest_key.keyBlob = key_blob_list[i - 1];
+ attest_key_opt = attest_key;
+ }
+
+ if ((i & 0x1) == 1) {
+ EXPECT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .EcdsaSigningKey(224)
+ .AttestKey()
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
+ &cert_chain_list[i]));
+ } else {
+ EXPECT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .AttestKey()
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
+ &cert_chain_list[i]));
+ }
+
+ AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+ AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+ EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+ cert_chain_list[i][0].encodedCertificate));
+
+ if (i > 0) {
+ /*
+ * The first key is attestated with factory chain, but all the rest of the keys are
+ * not supposed to be returned in attestation certificate chains.
+ */
+ EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i]));
+
+ // Appending the attest_key chain to the attested_key_chain should yield a valid chain.
+ cert_chain_list[i].insert(cert_chain_list[i].end(), //
+ cert_chain_list[i - 1].begin(), //
+ cert_chain_list[i - 1].end());
+ }
+
+ EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
+ 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, AllEcCurves) {
for (auto curve : ValidCurves()) {
/*
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index ad24364..8c3777f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -844,6 +844,66 @@
return result;
}
+void verify_serial(X509* cert, const uint64_t expected_serial) {
+ BIGNUM_Ptr ser(BN_new());
+ EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get()));
+
+ uint64_t serial;
+ EXPECT_TRUE(BN_get_u64(ser.get(), &serial));
+ EXPECT_EQ(serial, expected_serial);
+}
+
+// Please set self_signed to true for fake certificates or self signed
+// certificates
+void verify_subject(const X509* cert, //
+ const string& subject, //
+ bool self_signed) {
+ char* cert_issuer = //
+ X509_NAME_oneline(X509_get_issuer_name(cert), nullptr, 0);
+
+ char* cert_subj = X509_NAME_oneline(X509_get_subject_name(cert), nullptr, 0);
+
+ string expected_subject("/CN=");
+ if (subject.empty()) {
+ expected_subject.append("Android Keystore Key");
+ } else {
+ expected_subject.append(subject);
+ }
+
+ EXPECT_STREQ(expected_subject.c_str(), cert_subj) << "Cert has wrong subject." << cert_subj;
+
+ if (self_signed) {
+ EXPECT_STREQ(cert_issuer, cert_subj)
+ << "Cert issuer and subject mismatch for self signed certificate.";
+ }
+
+ OPENSSL_free(cert_subj);
+ OPENSSL_free(cert_issuer);
+}
+
+vector<uint8_t> build_serial_blob(const uint64_t serial_int) {
+ BIGNUM_Ptr serial(BN_new());
+ EXPECT_TRUE(BN_set_u64(serial.get(), serial_int));
+
+ int len = BN_num_bytes(serial.get());
+ vector<uint8_t> serial_blob(len);
+ if (BN_bn2bin(serial.get(), serial_blob.data()) != len) {
+ return {};
+ }
+
+ return serial_blob;
+}
+
+void verify_subject_and_serial(const Certificate& certificate, //
+ const uint64_t expected_serial, //
+ const string& subject, bool self_signed) {
+ X509_Ptr cert(parse_cert_blob(certificate.encodedCertificate));
+ ASSERT_TRUE(!!cert.get());
+
+ verify_serial(cert.get(), expected_serial);
+ verify_subject(cert.get(), subject, self_signed);
+}
+
bool verify_attestation_record(const string& challenge, //
const string& app_id, //
AuthorizationSet expected_sw_enforced, //
@@ -1081,17 +1141,10 @@
string cert_issuer = x509NameToStr(X509_get_issuer_name(key_cert.get()));
string signer_subj = x509NameToStr(X509_get_subject_name(signing_cert.get()));
if (cert_issuer != signer_subj) {
- return AssertionFailure() << "Cert " << i << " has wrong issuer.\n" << cert_data.str();
- }
-
- if (i == 0) {
- string cert_sub = x509NameToStr(X509_get_subject_name(key_cert.get()));
- if ("/CN=Android Keystore Key" != cert_sub) {
- return AssertionFailure()
- << "Leaf cert has wrong subject, should be CN=Android Keystore Key, was "
- << cert_sub << '\n'
- << cert_data.str();
- }
+ return AssertionFailure() << "Cert " << i << " has wrong issuer.\n"
+ << " Signer subject is " << signer_subj
+ << " Issuer subject is " << cert_issuer << endl
+ << cert_data.str();
}
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index da174ce..75a4418 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -269,12 +269,20 @@
long challenge_;
};
+vector<uint8_t> build_serial_blob(const uint64_t serial_int);
+void verify_subject(const X509* cert, const string& subject, bool self_signed);
+void verify_serial(X509* cert, const uint64_t expected_serial);
+void verify_subject_and_serial(const Certificate& certificate, //
+ const uint64_t expected_serial, //
+ const string& subject, bool self_signed);
+
bool verify_attestation_record(const string& challenge, //
const string& app_id, //
AuthorizationSet expected_sw_enforced, //
AuthorizationSet expected_hw_enforced, //
SecurityLevel security_level,
const vector<uint8_t>& attestation_cert);
+
string bin2hex(const vector<uint8_t>& data);
X509_Ptr parse_cert_blob(const vector<uint8_t>& blob);
vector<uint8_t> make_name_from_str(const string& name);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index c44526c..a89cc5b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -362,18 +362,27 @@
auto challenge = "hello";
auto app_id = "foo";
+ auto subject = "cert subj 2";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 66;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -385,6 +394,7 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
ASSERT_GT(cert_chain_.size(), 0);
@@ -480,16 +490,25 @@
auto challenge = "hello";
auto app_id = "foo";
+ auto subject = "subj 2";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 111166;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaEncryptionKey(key_size, 65537)
- .Padding(PaddingMode::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaEncryptionKey(key_size, 65537)
+ .Padding(PaddingMode::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
AuthorizationSet auths;
@@ -521,6 +540,7 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
ASSERT_GT(cert_chain_.size(), 0);
@@ -541,16 +561,25 @@
* works as expected.
*/
TEST_P(NewKeyGenerationTest, RsaWithSelfSign) {
+ auto subject = "cert subj subj subj subj subj subj 22222222222222222222";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 0;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -562,6 +591,7 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
ASSERT_EQ(cert_chain_.size(), 1);
@@ -599,16 +629,25 @@
auto key_size = 2048;
auto app_id = "foo";
+ auto subject = "cert subj 2";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 1;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -620,6 +659,7 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
ASSERT_EQ(cert_chain_.size(), 1);
@@ -676,19 +716,28 @@
auto challenge = "hello";
auto app_id = "foo";
+ auto subject = "cert subj 2";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 66;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_USAGE_COUNT_LIMIT, 1)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -711,6 +760,7 @@
// Check the usage count limit tag also appears in the attestation.
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
ASSERT_GT(cert_chain_.size(), 0);
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -794,17 +844,26 @@
auto challenge = "hello";
auto app_id = "foo";
+ auto subject = "cert subj 2";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 0xFFFFFFFFFFFFFFFF;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .EcdsaSigningKey(key_size)
- .Digest(Digest::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(key_size)
+ .Digest(Digest::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -816,6 +875,7 @@
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
ASSERT_GT(cert_chain_.size(), 0);
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -834,14 +894,23 @@
* the key will generate a self signed attestation.
*/
TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) {
+ auto subject = "cert subj 2";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+
+ uint64_t serial_int = 0x123456FFF1234;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .EcdsaSigningKey(key_size)
- .Digest(Digest::NONE)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .EcdsaSigningKey(key_size)
+ .Digest(Digest::NONE)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -852,6 +921,7 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
ASSERT_EQ(cert_chain_.size(), 1);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index ae21125..5b2a6f3 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -153,7 +153,7 @@
TAG_RESET_SINCE_ID_ROTATION_t, TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t,
TAG_DIGEST_t, TAG_PADDING_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t,
TAG_BOOT_PATCHLEVEL_t, TAG_VENDOR_PATCHLEVEL_t, TAG_TRUSTED_CONFIRMATION_REQUIRED_t,
- TAG_TRUSTED_USER_PRESENCE_REQUIRED_t>;
+ TAG_TRUSTED_USER_PRESENCE_REQUIRED_t, TAG_CERTIFICATE_SERIAL_t, TAG_CERTIFICATE_SUBJECT_t>;
template <typename TypedTagType>
struct TypedTag2ValueType;
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index e4fe52c..bdca32c 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -25,6 +25,7 @@
#include "supplicant_hidl_call_util.h"
#include "supplicant_hidl_test_utils.h"
+#include <cutils/properties.h>
using ::android::sp;
using ::android::hardware::hidl_array;
@@ -61,7 +62,7 @@
constexpr uint32_t kTestRadioWorkFrequency = 2412;
constexpr uint32_t kTestRadioWorkTimeout = 8;
constexpr uint32_t kTestRadioWorkId = 16;
-constexpr int8_t kTestCountryCode[] = {'U', 'S'};
+int8_t kTestCountryCode[] = {'U', 'S'};
constexpr uint8_t kTestWpsDeviceType[] = {[0 ... 7] = 0x01};
constexpr uint16_t kTestWpsConfigMethods = 0xffff;
} // namespace
@@ -454,6 +455,10 @@
* SetCountryCode.
*/
TEST_P(SupplicantStaIfaceHidlTest, SetCountryCode) {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ property_get("ro.boot.wificountrycode", buffer.data(), "US");
+ kTestCountryCode[0] = buffer.data()[0];
+ kTestCountryCode[1] = buffer.data()[1];
sta_iface_->setCountryCode(
kTestCountryCode, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);