Merge "Add test ensuring that BCC keys not unique ids" into sc-dev
diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
index 79243b6..a92a277 100644
--- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
+++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
@@ -225,14 +225,6 @@
return isTelephonyDevice(stringToAudioDevice(device));
}
-static inline bool isEchoReferenceDevice(AudioDevice device) {
- return device == AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE;
-}
-
-static inline bool isEchoReferenceDevice(const std::string& device) {
- return isEchoReferenceDevice(stringToAudioDevice(device));
-}
-
static inline bool maybeVendorExtension(const std::string& s) {
// Only checks whether the string starts with the "vendor prefix".
static const std::string vendorPrefix = "VX_";
diff --git a/audio/common/all-versions/test/utility/Android.bp b/audio/common/all-versions/test/utility/Android.bp
index 1602d25..757f8a8 100644
--- a/audio/common/all-versions/test/utility/Android.bp
+++ b/audio/common/all-versions/test/utility/Android.bp
@@ -25,7 +25,7 @@
cc_library_static {
name: "android.hardware.audio.common.test.utility",
- defaults : ["hidl_defaults"],
+ defaults: ["hidl_defaults"],
srcs: ["src/ValidateXml.cpp"],
cflags: [
"-O0",
@@ -34,7 +34,34 @@
],
local_include_dirs: ["include/utility"],
export_include_dirs: ["include"],
- shared_libs: ["libxml2", "liblog"],
+ shared_libs: [
+ "libxml2",
+ "liblog",
+ ],
static_libs: ["libgtest"],
export_static_lib_headers: ["libgtest"],
}
+
+// Note: this isn't a VTS test, but rather a unit test
+// to verify correctness of test utilities.
+cc_test {
+ name: "android.hardware.audio.common.test.utility_tests",
+ host_supported: true,
+ local_include_dirs: ["include/utility"],
+ srcs: [
+ "src/ValidateXml.cpp",
+ "tests/utility_tests.cpp",
+ ],
+ cflags: [
+ "-Werror",
+ "-Wall",
+ "-g",
+ ],
+ shared_libs: [
+ "libbase",
+ "libxml2",
+ "liblog",
+ ],
+ static_libs: ["libgtest"],
+ test_suites: ["general-tests"],
+}
diff --git a/audio/common/all-versions/test/utility/TEST_MAPPING b/audio/common/all-versions/test/utility/TEST_MAPPING
new file mode 100644
index 0000000..0bc1871
--- /dev/null
+++ b/audio/common/all-versions/test/utility/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "android.hardware.audio.common.test.utility_tests"
+ }
+ ]
+}
diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
index a866104..f111c01 100644
--- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp
+++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
@@ -112,7 +112,8 @@
return ::testing::AssertionFailure() << "Failed to parse xml\n" << context();
}
- if (xmlXIncludeProcess(doc.get()) == -1) {
+ // Process 'include' directives w/o modifying elements loaded from included files.
+ if (xmlXIncludeProcessFlags(doc.get(), XML_PARSE_NOBASEFIX) == -1) {
return ::testing::AssertionFailure() << "Failed to resolve xincludes in xml\n" << context();
}
diff --git a/audio/common/all-versions/test/utility/tests/utility_tests.cpp b/audio/common/all-versions/test/utility/tests/utility_tests.cpp
new file mode 100644
index 0000000..c523066
--- /dev/null
+++ b/audio/common/all-versions/test/utility/tests/utility_tests.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#include <android-base/file.h>
+#include <gtest/gtest.h>
+
+#include <ValidateXml.h>
+
+using ::android::hardware::audio::common::test::utility::validateXml;
+
+const char* XSD_SOURCE =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xs:schema version=\"2.0\""
+ " elementFormDefault=\"qualified\""
+ " attributeFormDefault=\"unqualified\""
+ " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
+ " <xs:element name=\"audioPolicyConfiguration\">"
+ " <xs:complexType>"
+ " <xs:sequence>"
+ " <xs:element name=\"modules\">"
+ " <xs:complexType>"
+ " <xs:sequence>"
+ " <xs:element name=\"module\" maxOccurs=\"unbounded\">"
+ " <xs:complexType>"
+ " <xs:attribute name=\"name\" type=\"xs:string\" use=\"required\"/>"
+ " </xs:complexType>"
+ " </xs:element>"
+ " </xs:sequence>"
+ " </xs:complexType>"
+ " </xs:element>"
+ " </xs:sequence>"
+ " </xs:complexType>"
+ " </xs:element>"
+ "</xs:schema>";
+
+const char* INVALID_XML_SOURCE =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<audioPolicyKonfiguration />";
+
+const char* VALID_XML_SOURCE =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<audioPolicyConfiguration>"
+ " <modules>"
+ " <module name=\"aaa\" />"
+ " %s"
+ " </modules>"
+ "</audioPolicyConfiguration>";
+
+const char* MODULE_SOURCE = "<module name=\"bbb\" />";
+
+const char* XI_INCLUDE = "<xi:include xmlns:xi=\"http://www.w3.org/2001/XInclude\" href=\"%s\" />";
+
+const char* XML_INCLUDED_SOURCE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>%s";
+
+namespace {
+
+std::string substitute(const char* fmt, const char* param) {
+ std::string buffer(static_cast<size_t>(strlen(fmt) + strlen(param)), '\0');
+ snprintf(buffer.data(), buffer.size(), fmt, param);
+ return buffer;
+}
+
+std::string substitute(const char* fmt, const std::string& s) {
+ return substitute(fmt, s.c_str());
+}
+
+} // namespace
+
+TEST(ValidateXml, InvalidXml) {
+ TemporaryFile xml;
+ ASSERT_TRUE(android::base::WriteStringToFile(INVALID_XML_SOURCE, xml.path)) << strerror(errno);
+ TemporaryFile xsd;
+ ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+ EXPECT_FALSE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, ValidXml) {
+ TemporaryFile xml;
+ ASSERT_TRUE(
+ android::base::WriteStringToFile(substitute(VALID_XML_SOURCE, MODULE_SOURCE), xml.path))
+ << strerror(errno);
+ TemporaryFile xsd;
+ ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+ EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, IncludeAbsolutePath) {
+ TemporaryFile xmlInclude;
+ ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE),
+ xmlInclude.path))
+ << strerror(errno);
+ TemporaryFile xml;
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ substitute(VALID_XML_SOURCE, substitute(XI_INCLUDE, xmlInclude.path)), xml.path))
+ << strerror(errno);
+ TemporaryFile xsd;
+ ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+ EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, IncludeSameDirRelativePath) {
+ TemporaryFile xmlInclude;
+ ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE),
+ xmlInclude.path))
+ << strerror(errno);
+ TemporaryFile xml;
+ ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlInclude.path));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ substitute(VALID_XML_SOURCE,
+ substitute(XI_INCLUDE, android::base::Basename(xmlInclude.path))),
+ xml.path))
+ << strerror(errno);
+ TemporaryFile xsd;
+ ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+ EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, IncludeSubdirRelativePath) {
+ TemporaryDir xmlIncludeDir;
+ TemporaryFile xmlInclude(xmlIncludeDir.path);
+ ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE),
+ xmlInclude.path))
+ << strerror(errno);
+ TemporaryFile xml;
+ ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlIncludeDir.path));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ substitute(VALID_XML_SOURCE,
+ substitute(XI_INCLUDE, android::base::Basename(xmlIncludeDir.path) + "/" +
+ android::base::Basename(xmlInclude.path))),
+ xml.path))
+ << strerror(errno);
+ TemporaryFile xsd;
+ ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+ EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, IncludeParentDirRelativePath) {
+ // An XML file from a subdirectory includes a file from the parent directory using '..' syntax.
+ TemporaryFile xmlInclude;
+ ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE),
+ xmlInclude.path))
+ << strerror(errno);
+ TemporaryDir xmlIncludeDir;
+ TemporaryFile xmlParentInclude(xmlIncludeDir.path);
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ substitute(XML_INCLUDED_SOURCE,
+ substitute(XI_INCLUDE, "../" + android::base::Basename(xmlInclude.path))),
+ xmlParentInclude.path))
+ << strerror(errno);
+ TemporaryFile xml;
+ ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlInclude.path));
+ ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlIncludeDir.path));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ substitute(
+ VALID_XML_SOURCE,
+ substitute(XI_INCLUDE, android::base::Basename(xmlIncludeDir.path) + "/" +
+ android::base::Basename(xmlParentInclude.path))),
+ xml.path))
+ << strerror(errno);
+ TemporaryFile xsd;
+ ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+ EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 79ac295..0b3098b 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -710,8 +710,7 @@
// Returning 'true' when no source is found so the test can fail later with a more clear
// problem description.
return !maybeSourceAddress.has_value() ||
- !(xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType) ||
- xsd::isEchoReferenceDevice(maybeSourceAddress.value().deviceType));
+ !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType);
}
void createPatchIfNeeded() {
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index d980c5f..0cb7c95 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -34,12 +34,15 @@
}
};
-Session::Session(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {}
+Session::Session(std::shared_ptr<ISessionCallback> cb)
+ : cb_(std::move(cb)), mRandom(std::mt19937::default_seed) {}
ndk::ScopedAStatus Session::generateChallenge() {
LOG(INFO) << "generateChallenge";
if (cb_) {
- cb_->onChallengeGenerated(0);
+ std::uniform_int_distribution<int64_t> dist;
+ auto challenge = dist(mRandom);
+ cb_->onChallengeGenerated(challenge);
}
return ndk::ScopedAStatus::ok();
}
@@ -63,6 +66,9 @@
const std::vector<Feature>& /*features*/, const NativeHandle& /*previewSurface*/,
std::shared_ptr<biometrics::common::ICancellationSignal>* /*return_val*/) {
LOG(INFO) << "enroll";
+ if (cb_) {
+ cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ }
return ndk::ScopedAStatus::ok();
}
@@ -100,6 +106,9 @@
ndk::ScopedAStatus Session::getFeatures() {
LOG(INFO) << "getFeatures";
+ if (cb_) {
+ cb_->onFeaturesRetrieved({});
+ }
return ndk::ScopedAStatus::ok();
}
@@ -119,6 +128,9 @@
ndk::ScopedAStatus Session::invalidateAuthenticatorId() {
LOG(INFO) << "invalidateAuthenticatorId";
+ if (cb_) {
+ cb_->onAuthenticatorIdInvalidated(0);
+ }
return ndk::ScopedAStatus::ok();
}
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index caf81f8..4d213e3 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -16,6 +16,8 @@
#pragma once
+#include <random>
+
#include <aidl/android/hardware/biometrics/face/BnSession.h>
#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
@@ -68,6 +70,7 @@
private:
std::shared_ptr<ISessionCallback> cb_;
+ std::mt19937 mRandom;
};
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
index 47a7813..4dc44f1 100644
--- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
+++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
@@ -29,16 +29,26 @@
using namespace std::literals::chrono_literals;
+using aidl::android::hardware::common::NativeHandle;
+
constexpr int kSensorId = 0;
constexpr int kUserId = 0;
class SessionCallback : public BnSessionCallback {
public:
- ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+ ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnChallengeGeneratedInvoked = true;
+ mGeneratedChallenge = challenge;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+ ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnChallengeRevokedInvoked = true;
+ mRevokedChallenge = challenge;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
@@ -50,10 +60,9 @@
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onError(Error error, int32_t vendorCode) override {
+ ndk::ScopedAStatus onError(Error error, int32_t /*vendorCode*/) override {
auto lock = std::lock_guard<std::mutex>{mMutex};
mError = error;
- mVendorCode = vendorCode;
mOnErrorInvoked = true;
mCv.notify_one();
return ndk::ScopedAStatus::ok();
@@ -83,15 +92,24 @@
ndk::ScopedAStatus onEnrollmentsEnumerated(
const std::vector<int32_t>& /*enrollmentIds*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnEnrollmentsEnumeratedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onEnrollmentsRemoved(
const std::vector<int32_t>& /*enrollmentIds*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnEnrollmentsRemovedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>& /*features*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnFeaturesRetrievedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
@@ -100,10 +118,16 @@
}
ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnAuthenticatorIdRetrievedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*newAuthenticatorId*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnAuthenticatorIdInvalidatedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
@@ -117,46 +141,177 @@
std::mutex mMutex;
std::condition_variable mCv;
Error mError = Error::UNKNOWN;
- int32_t mVendorCode = 0;
+ int64_t mGeneratedChallenge = 0;
+ int64_t mRevokedChallenge = 0;
+ bool mOnChallengeGeneratedInvoked = false;
+ bool mOnChallengeRevokedInvoked = false;
bool mOnErrorInvoked = false;
+ bool mOnEnrollmentsEnumeratedInvoked = false;
+ bool mOnEnrollmentsRemovedInvoked = false;
+ bool mOnFeaturesRetrievedInvoked = false;
+ bool mOnAuthenticatorIdRetrievedInvoked = false;
+ bool mOnAuthenticatorIdInvalidatedInvoked = false;
bool mOnSessionClosedInvoked = false;
};
class Face : public testing::TestWithParam<std::string> {
protected:
void SetUp() override {
- AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
- ASSERT_NE(binder, nullptr);
- mHal = IFace::fromBinder(ndk::SpAIBinder(binder));
+ // Prepare the callback.
+ mCb = ndk::SharedRefBase::make<SessionCallback>();
+
+ int retries = 0;
+ bool isOk = false;
+ // If the first attempt to create a session fails, we try to create a session again. The
+ // first attempt might fail if the framework already has an active session. The AIDL
+ // contract doesn't allow to create a new session without closing the old one. However, we
+ // can't close the framework's session from VTS. The expectation here is that the HAL will
+ // crash after the first illegal attempt to create a session, then it will restart, and then
+ // we'll be able to create a session.
+ do {
+ // Get an instance of the HAL.
+ AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+ ASSERT_NE(binder, nullptr);
+ mHal = IFace::fromBinder(ndk::SpAIBinder(binder));
+
+ // Create a session.
+ isOk = mHal->createSession(kSensorId, kUserId, mCb, &mSession).isOk();
+ ++retries;
+ } while (!isOk && retries < 2);
+
+ ASSERT_TRUE(isOk);
+ }
+
+ void TearDown() override {
+ // Close the mSession.
+ ASSERT_TRUE(mSession->close().isOk());
+
+ // Make sure the mSession is closed.
+ auto lock = std::unique_lock<std::mutex>(mCb->mMutex);
+ mCb->mCv.wait(lock, [this] { return mCb->mOnSessionClosedInvoked; });
}
std::shared_ptr<IFace> mHal;
+ std::shared_ptr<SessionCallback> mCb;
+ std::shared_ptr<ISession> mSession;
};
-TEST_P(Face, AuthenticateTest) {
- // Prepare the callback.
- auto cb = ndk::SharedRefBase::make<SessionCallback>();
+TEST_P(Face, GetSensorPropsWorksTest) {
+ std::vector<SensorProps> sensorProps;
- // Create a session
- std::shared_ptr<ISession> session;
- ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk());
+ // Call the method.
+ ASSERT_TRUE(mHal->getSensorProps(&sensorProps).isOk());
- // Call authenticate
+ // Make sure the sensorProps aren't empty.
+ ASSERT_FALSE(sensorProps.empty());
+ ASSERT_FALSE(sensorProps[0].commonProps.componentInfo.empty());
+}
+
+TEST_P(Face, EnrollWithBadHatResultsInErrorTest) {
+ // Call the method.
+ auto hat = keymaster::HardwareAuthToken{};
std::shared_ptr<common::ICancellationSignal> cancellationSignal;
- ASSERT_TRUE(session->authenticate(0 /* operationId */, &cancellationSignal).isOk());
+ ASSERT_TRUE(
+ mSession->enroll(hat, EnrollmentType::DEFAULT, {}, NativeHandle{}, &cancellationSignal)
+ .isOk());
- auto lock = std::unique_lock<std::mutex>(cb->mMutex);
- cb->mCv.wait(lock, [&cb] { return cb->mOnErrorInvoked; });
- // Get the results
- EXPECT_EQ(cb->mError, Error::UNABLE_TO_PROCESS);
- EXPECT_EQ(cb->mVendorCode, 0);
+ // Make sure an error is returned.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; });
+}
+
+TEST_P(Face, GenerateChallengeProducesUniqueChallengesTest) {
+ static constexpr int kIterations = 100;
+
+ auto challenges = std::set<int>{};
+ for (unsigned int i = 0; i < kIterations; ++i) {
+ // Call the method.
+ ASSERT_TRUE(mSession->generateChallenge().isOk());
+
+ // Check that the generated challenge is unique and not 0.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; });
+ ASSERT_NE(mCb->mGeneratedChallenge, 0);
+ ASSERT_EQ(challenges.find(mCb->mGeneratedChallenge), challenges.end());
+
+ challenges.insert(mCb->mGeneratedChallenge);
+ mCb->mOnChallengeGeneratedInvoked = false;
+ }
+}
+
+TEST_P(Face, RevokeChallengeWorksForNonexistentChallengeTest) {
+ const int64_t nonexistentChallenge = 123;
+
+ // Call the method.
+ ASSERT_TRUE(mSession->revokeChallenge(nonexistentChallenge).isOk());
+
+ // Check that the challenge is revoked and matches the requested challenge.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; });
+ ASSERT_EQ(mCb->mRevokedChallenge, nonexistentChallenge);
+}
+
+TEST_P(Face, RevokeChallengeWorksForExistentChallengeTest) {
+ // Generate a challenge.
+ ASSERT_TRUE(mSession->generateChallenge().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; });
lock.unlock();
- // Close the session
- ASSERT_TRUE(session->close().isOk());
+ // Revoke the challenge.
+ ASSERT_TRUE(mSession->revokeChallenge(mCb->mGeneratedChallenge).isOk());
+ // Check that the challenge is revoked and matches the requested challenge.
lock.lock();
- cb->mCv.wait(lock, [&cb] { return cb->mOnSessionClosedInvoked; });
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; });
+ ASSERT_EQ(mCb->mRevokedChallenge, mCb->mGeneratedChallenge);
+}
+
+TEST_P(Face, EnumerateEnrollmentsWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->enumerateEnrollments().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsEnumeratedInvoked; });
+}
+
+TEST_P(Face, RemoveEnrollmentsWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->removeEnrollments({}).isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsRemovedInvoked; });
+}
+
+TEST_P(Face, GetFeaturesWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->getFeatures().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnFeaturesRetrievedInvoked; });
+}
+
+TEST_P(Face, GetAuthenticatorIdWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->getAuthenticatorId().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdRetrievedInvoked; });
+}
+
+TEST_P(Face, InvalidateAuthenticatorIdWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->invalidateAuthenticatorId().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdInvalidatedInvoked; });
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Face);
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 6667f7a..b927770 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -17,14 +17,19 @@
#pragma once
#include <android-base/logging.h>
+#include <random>
namespace aidl::android::hardware::biometrics::fingerprint {
class FakeFingerprintEngine {
public:
+ FakeFingerprintEngine() : mRandom(std::mt19937::default_seed) {}
+
void generateChallengeImpl(ISessionCallback* cb) {
LOG(INFO) << "generateChallengeImpl";
- cb->onChallengeGenerated(0 /* challenge */);
+ std::uniform_int_distribution<int64_t> dist;
+ auto challenge = dist(mRandom);
+ cb->onChallengeGenerated(challenge);
}
void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
@@ -32,8 +37,13 @@
cb->onChallengeRevoked(challenge);
}
- void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/) {
+ void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat) {
LOG(INFO) << "enrollImpl";
+ // Do proper HAT verification in the real implementation.
+ if (hat.mac.empty()) {
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
cb->onEnrollmentProgress(0 /* enrollmentId */, 0 /* remaining */);
}
@@ -71,6 +81,8 @@
LOG(INFO) << "resetLockoutImpl";
cb->onLockoutCleared();
}
+
+ std::mt19937 mRandom;
};
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
index f1cfb17..1cd8c76 100644
--- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
+++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
@@ -35,13 +35,19 @@
class SessionCallback : public BnSessionCallback {
public:
- explicit SessionCallback(std::promise<void>&& promise) : mPromise(std::move(promise)) {}
-
- ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+ ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnChallengeGeneratedInvoked = true;
+ mGeneratedChallenge = challenge;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+ ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnChallengeRevokedInvoked = true;
+ mRevokedChallenge = challenge;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
@@ -49,7 +55,11 @@
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onError(Error /*error*/, int32_t /*vendorCode*/) override {
+ ndk::ScopedAStatus onError(Error error, int32_t /*vendorCode*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mError = error;
+ mOnErrorInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
@@ -77,63 +87,203 @@
ndk::ScopedAStatus onEnrollmentsEnumerated(
const std::vector<int32_t>& /*enrollmentIds*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnEnrollmentsEnumeratedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onEnrollmentsRemoved(
const std::vector<int32_t>& /*enrollmentIds*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnEnrollmentsRemovedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnAuthenticatorIdRetrievedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*newAuthenticatorId*/) override {
+ auto lock = std::lock_guard{mMutex};
+ mOnAuthenticatorIdInvalidatedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus onSessionClosed() override {
- mPromise.set_value();
+ auto lock = std::lock_guard{mMutex};
+ mOnSessionClosedInvoked = true;
+ mCv.notify_one();
return ndk::ScopedAStatus::ok();
}
- private:
- std::promise<void> mPromise;
+ std::mutex mMutex;
+ std::condition_variable mCv;
+ Error mError = Error::UNKNOWN;
+ int64_t mGeneratedChallenge = 0;
+ int64_t mRevokedChallenge = 0;
+ bool mOnChallengeGeneratedInvoked = false;
+ bool mOnChallengeRevokedInvoked = false;
+ bool mOnErrorInvoked = false;
+ bool mOnEnrollmentsEnumeratedInvoked = false;
+ bool mOnEnrollmentsRemovedInvoked = false;
+ bool mOnAuthenticatorIdRetrievedInvoked = false;
+ bool mOnAuthenticatorIdInvalidatedInvoked = false;
+ bool mOnSessionClosedInvoked = false;
};
class Fingerprint : public testing::TestWithParam<std::string> {
protected:
void SetUp() override {
- AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
- ASSERT_NE(binder, nullptr);
- mHal = IFingerprint::fromBinder(ndk::SpAIBinder(binder));
+ // Prepare the callback.
+ mCb = ndk::SharedRefBase::make<SessionCallback>();
+
+ int retries = 0;
+ bool isOk = false;
+ // If the first attempt to create a session fails, we try to create a session again. The
+ // first attempt might fail if the framework already has an active session. The AIDL
+ // contract doesn't allow to create a new session without closing the old one. However, we
+ // can't close the framework's session from VTS. The expectation here is that the HAL will
+ // crash after the first illegal attempt to create a session, then it will restart, and then
+ // we'll be able to create a session.
+ do {
+ // Get an instance of the HAL.
+ AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+ ASSERT_NE(binder, nullptr);
+ mHal = IFingerprint::fromBinder(ndk::SpAIBinder(binder));
+
+ // Create a session.
+ isOk = mHal->createSession(kSensorId, kUserId, mCb, &mSession).isOk();
+ ++retries;
+ } while (!isOk && retries < 2);
+
+ ASSERT_TRUE(isOk);
+ }
+
+ void TearDown() override {
+ // Close the mSession.
+ ASSERT_TRUE(mSession->close().isOk());
+
+ // Make sure the mSession is closed.
+ auto lock = std::unique_lock<std::mutex>(mCb->mMutex);
+ mCb->mCv.wait(lock, [this] { return mCb->mOnSessionClosedInvoked; });
}
std::shared_ptr<IFingerprint> mHal;
+ std::shared_ptr<SessionCallback> mCb;
+ std::shared_ptr<ISession> mSession;
};
-TEST_P(Fingerprint, AuthenticateTest) {
- auto promise = std::promise<void>{};
- auto future = promise.get_future();
- // Prepare the callback.
- auto cb = ndk::SharedRefBase::make<SessionCallback>(std::move(promise));
+TEST_P(Fingerprint, GetSensorPropsWorksTest) {
+ std::vector<SensorProps> sensorProps;
- // Create a session
- std::shared_ptr<ISession> session;
- ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk());
+ // Call the method.
+ ASSERT_TRUE(mHal->getSensorProps(&sensorProps).isOk());
- // Call authenticate
+ // Make sure the sensorProps aren't empty.
+ ASSERT_FALSE(sensorProps.empty());
+ ASSERT_FALSE(sensorProps[0].commonProps.componentInfo.empty());
+}
+
+TEST_P(Fingerprint, EnrollWithBadHatResultsInErrorTest) {
+ // Call the method.
+ auto hat = keymaster::HardwareAuthToken{};
std::shared_ptr<common::ICancellationSignal> cancellationSignal;
- ASSERT_TRUE(session->authenticate(-1 /* operationId */, &cancellationSignal).isOk());
+ ASSERT_TRUE(mSession->enroll(hat, &cancellationSignal).isOk());
- // Get the results
- // TODO(b/166799066): test authenticate.
+ // Make sure an error is returned.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; });
+}
- // Close the session
- ASSERT_TRUE(session->close().isOk());
- auto status = future.wait_for(1s);
- ASSERT_EQ(status, std::future_status::ready);
+TEST_P(Fingerprint, GenerateChallengeProducesUniqueChallengesTest) {
+ static constexpr int kIterations = 100;
+
+ auto challenges = std::set<int>{};
+ for (unsigned int i = 0; i < kIterations; ++i) {
+ // Call the method.
+ ASSERT_TRUE(mSession->generateChallenge().isOk());
+
+ // Check that the generated challenge is unique and not 0.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; });
+ ASSERT_NE(mCb->mGeneratedChallenge, 0);
+ ASSERT_EQ(challenges.find(mCb->mGeneratedChallenge), challenges.end());
+
+ challenges.insert(mCb->mGeneratedChallenge);
+ mCb->mOnChallengeGeneratedInvoked = false;
+ }
+}
+
+TEST_P(Fingerprint, RevokeChallengeWorksForNonexistentChallengeTest) {
+ const int64_t nonexistentChallenge = 123;
+
+ // Call the method.
+ ASSERT_TRUE(mSession->revokeChallenge(nonexistentChallenge).isOk());
+
+ // Check that the challenge is revoked and matches the requested challenge.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; });
+ ASSERT_EQ(mCb->mRevokedChallenge, nonexistentChallenge);
+}
+
+TEST_P(Fingerprint, RevokeChallengeWorksForExistentChallengeTest) {
+ // Generate a challenge.
+ ASSERT_TRUE(mSession->generateChallenge().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; });
+ lock.unlock();
+
+ // Revoke the challenge.
+ ASSERT_TRUE(mSession->revokeChallenge(mCb->mGeneratedChallenge).isOk());
+
+ // Check that the challenge is revoked and matches the requested challenge.
+ lock.lock();
+ mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; });
+ ASSERT_EQ(mCb->mRevokedChallenge, mCb->mGeneratedChallenge);
+}
+
+TEST_P(Fingerprint, EnumerateEnrollmentsWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->enumerateEnrollments().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsEnumeratedInvoked; });
+}
+
+TEST_P(Fingerprint, RemoveEnrollmentsWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->removeEnrollments({}).isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsRemovedInvoked; });
+}
+
+TEST_P(Fingerprint, GetAuthenticatorIdWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->getAuthenticatorId().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdRetrievedInvoked; });
+}
+
+TEST_P(Fingerprint, InvalidateAuthenticatorIdWorksTest) {
+ // Call the method.
+ ASSERT_TRUE(mSession->invalidateAuthenticatorId().isOk());
+
+ // Wait for the result.
+ auto lock = std::unique_lock{mCb->mMutex};
+ mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdInvalidatedInvoked; });
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Fingerprint);
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 4cecff7..2241735 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -813,9 +813,10 @@
byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob);
/**
- * Returns parameters associated with the provided key. This should match the
- * KeyCharacteristics present in the KeyCreationResult returned by generateKey(),
- * importKey(), or importWrappedKey().
+ * Returns KeyMint-enforced parameters associated with the provided key. The returned tags are
+ * a subset of KeyCharacteristics found in the KeyCreationResult returned by generateKey(),
+ * importKey(), or importWrappedKey(). The returned value is a subset, as it does not include
+ * any Keystore-enforced parameters.
*
* @param keyBlob The opaque descriptor returned by generateKey, importKey or importWrappedKey.
*
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 270574b..01bf54b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -18,10 +18,6 @@
import android.hardware.security.keymint.TagType;
-// TODO(seleneh) : note aidl currently does not support double nested enum definitions such as
-// ROOT_OF_TRUST = TagType:BYTES | 704. So we are forced to write definitions as
-// ROOT_OF_TRUST = (9 << 28) for now. Will need to flip this back later when aidl support is added.
-
/**
* Tag specifies various kinds of tags that can be set in KeyParameter to identify what kind of
* data are stored in KeyParameter.
@@ -33,7 +29,7 @@
/**
* Tag::INVALID should never be set. It means you hit an error.
*/
- INVALID = (0 << 28) | 0,
+ INVALID = 0,
/**
* Tag::PURPOSE specifies the set of purposes for which the key may be used. Possible values
@@ -47,7 +43,7 @@
*
* Must be hardware-enforced.
*/
- PURPOSE = (2 << 28) /* TagType:ENUM_REP */ | 1,
+ PURPOSE = TagType.ENUM_REP | 1,
/**
* Tag::ALGORITHM specifies the cryptographic algorithm with which the key is used. This tag
@@ -56,7 +52,7 @@
*
* Must be hardware-enforced.
*/
- ALGORITHM = (1 << 28) /* TagType:ENUM */ | 2,
+ ALGORITHM = TagType.ENUM | 2,
/**
* Tag::KEY_SIZE specifies the size, in bits, of the key, measuring in the normal way for the
@@ -68,7 +64,7 @@
*
* Must be hardware-enforced.
*/
- KEY_SIZE = (3 << 28) /* TagType:UINT */ | 3,
+ KEY_SIZE = TagType.UINT | 3,
/**
* Tag::BLOCK_MODE specifies the block cipher mode(s) with which the key may be used. This tag
@@ -81,7 +77,7 @@
*
* Must be hardware-enforced.
*/
- BLOCK_MODE = (2 << 28) /* TagType:ENUM_REP */ | 4,
+ BLOCK_MODE = TagType.ENUM_REP | 4,
/**
* Tag::DIGEST specifies the digest algorithms that may be used with the key to perform signing
@@ -95,7 +91,7 @@
*
* Must be hardware-enforced.
*/
- DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 5,
+ DIGEST = TagType.ENUM_REP | 5,
/**
* Tag::PADDING specifies the padding modes that may be used with the key. This tag is relevant
@@ -123,7 +119,7 @@
*
* Must be hardware-enforced.
*/
- PADDING = (2 << 28) /* TagType:ENUM_REP */ | 6,
+ PADDING = TagType.ENUM_REP | 6,
/**
* Tag::CALLER_NONCE specifies that the caller can provide a nonce for nonce-requiring
@@ -136,7 +132,7 @@
*
* Must be hardware-enforced.
*/
- CALLER_NONCE = (7 << 28) /* TagType:BOOL */ | 7,
+ CALLER_NONCE = TagType.BOOL | 7,
/**
* Tag::MIN_MAC_LENGTH specifies the minimum length of MAC that can be requested or verified
@@ -149,7 +145,7 @@
*
* Must be hardware-enforced.
*/
- MIN_MAC_LENGTH = (3 << 28) /* TagType:UINT */ | 8,
+ MIN_MAC_LENGTH = TagType.UINT | 8,
// Tag 9 reserved
@@ -159,7 +155,7 @@
*
* Must be hardware-enforced.
*/
- EC_CURVE = (1 << 28) /* TagType:ENUM */ | 10,
+ EC_CURVE = TagType.ENUM | 10,
/**
* Tag::RSA_PUBLIC_EXPONENT specifies the value of the public exponent for an RSA key pair.
@@ -173,7 +169,7 @@
*
* Must be hardware-enforced.
*/
- RSA_PUBLIC_EXPONENT = (5 << 28) /* TagType:ULONG */ | 200,
+ RSA_PUBLIC_EXPONENT = TagType.ULONG | 200,
// Tag 201 reserved
@@ -184,7 +180,7 @@
*
* Must be hardware-enforced.
*/
- INCLUDE_UNIQUE_ID = (7 << 28) /* TagType:BOOL */ | 202,
+ INCLUDE_UNIQUE_ID = TagType.BOOL | 202,
/**
* Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with RSA
@@ -197,7 +193,7 @@
*
* Must be hardware-enforced.
*/
- RSA_OAEP_MGF_DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 203,
+ RSA_OAEP_MGF_DIGEST = TagType.ENUM_REP | 203,
// Tag 301 reserved
@@ -209,7 +205,7 @@
*
* Must be hardware-enforced.
*/
- BOOTLOADER_ONLY = (7 << 28) /* TagType:BOOL */ | 302,
+ BOOTLOADER_ONLY = TagType.BOOL | 302,
/**
* Tag::ROLLBACK_RESISTANCE specifies that the key has rollback resistance, meaning that when
@@ -224,10 +220,10 @@
*
* Must be hardware-enforced.
*/
- ROLLBACK_RESISTANCE = (7 << 28) /* TagType:BOOL */ | 303,
+ ROLLBACK_RESISTANCE = TagType.BOOL | 303,
// Reserved for future use.
- HARDWARE_TYPE = (1 << 28) /* TagType:ENUM */ | 304,
+ HARDWARE_TYPE = TagType.ENUM | 304,
/**
* Keys tagged with EARLY_BOOT_ONLY may only be used during early boot, until
@@ -236,7 +232,7 @@
* provided to IKeyMintDevice::importKey, the import must fail with
* ErrorCode::EARLY_BOOT_ENDED.
*/
- EARLY_BOOT_ONLY = (7 << 28) /* TagType:BOOL */ | 305,
+ EARLY_BOOT_ONLY = TagType.BOOL | 305,
/**
* Tag::ACTIVE_DATETIME specifies the date and time at which the key becomes active, in
@@ -245,7 +241,7 @@
*
* Need not be hardware-enforced.
*/
- ACTIVE_DATETIME = (6 << 28) /* TagType:DATE */ | 400,
+ ACTIVE_DATETIME = TagType.DATE | 400,
/**
* Tag::ORIGINATION_EXPIRE_DATETIME specifies the date and time at which the key expires for
@@ -257,7 +253,7 @@
*
* Need not be hardware-enforced.
*/
- ORIGINATION_EXPIRE_DATETIME = (6 << 28) /* TagType:DATE */ | 401,
+ ORIGINATION_EXPIRE_DATETIME = TagType.DATE | 401,
/**
* Tag::USAGE_EXPIRE_DATETIME specifies the date and time at which the key expires for
@@ -269,7 +265,7 @@
*
* Need not be hardware-enforced.
*/
- USAGE_EXPIRE_DATETIME = (6 << 28) /* TagType:DATE */ | 402,
+ USAGE_EXPIRE_DATETIME = TagType.DATE | 402,
/**
* TODO(seleneh) this tag need to be deleted.
@@ -293,8 +289,10 @@
* fails because the table is full, KeyMint returns ErrorCode::TOO_MANY_OPERATIONS.
*
* Must be hardware-enforced.
+ *
+ * TODO(b/191738660): Remove in KeyMint V2. Currently only used for FDE.
*/
- MIN_SECONDS_BETWEEN_OPS = (3 << 28) /* TagType:UINT */ | 403,
+ MIN_SECONDS_BETWEEN_OPS = TagType.UINT | 403,
/**
* Tag::MAX_USES_PER_BOOT specifies the maximum number of times that a key may be used between
@@ -314,7 +312,7 @@
*
* Must be hardware-enforced.
*/
- MAX_USES_PER_BOOT = (3 << 28) /* TagType:UINT */ | 404,
+ MAX_USES_PER_BOOT = TagType.UINT | 404,
/**
* Tag::USAGE_COUNT_LIMIT specifies the number of times that a key may be used. This can be
@@ -343,14 +341,14 @@
* record. This tag must have the same SecurityLevel as the tag that is added to the key
* characteristics.
*/
- USAGE_COUNT_LIMIT = (3 << 28) | 405, /* TagType:UINT */
+ USAGE_COUNT_LIMIT = TagType.UINT | 405,
/**
* Tag::USER_ID specifies the ID of the Android user that is permitted to use the key.
*
* Must not be hardware-enforced.
*/
- USER_ID = (3 << 28) /* TagType:UINT */ | 501,
+ USER_ID = TagType.UINT | 501,
/**
* Tag::USER_SECURE_ID specifies that a key may only be used under a particular secure user
@@ -383,7 +381,7 @@
*
* Must be hardware-enforced.
*/
- USER_SECURE_ID = (10 << 28) /* TagType:ULONG_REP */ | 502,
+ USER_SECURE_ID = TagType.ULONG_REP | 502,
/**
* Tag::NO_AUTH_REQUIRED specifies that no authentication is required to use this key. This tag
@@ -391,7 +389,7 @@
*
* Must be hardware-enforced.
*/
- NO_AUTH_REQUIRED = (7 << 28) /* TagType:BOOL */ | 503,
+ NO_AUTH_REQUIRED = TagType.BOOL | 503,
/**
* Tag::USER_AUTH_TYPE specifies the types of user authenticators that may be used to authorize
@@ -410,7 +408,7 @@
*
* Must be hardware-enforced.
*/
- USER_AUTH_TYPE = (1 << 28) /* TagType:ENUM */ | 504,
+ USER_AUTH_TYPE = TagType.ENUM | 504,
/**
* Tag::AUTH_TIMEOUT specifies the time in seconds for which the key is authorized for use,
@@ -424,7 +422,7 @@
*
* Must be hardware-enforced.
*/
- AUTH_TIMEOUT = (3 << 28) /* TagType:UINT */ | 505,
+ AUTH_TIMEOUT = TagType.UINT | 505,
/**
* Tag::ALLOW_WHILE_ON_BODY specifies that the key may be used after authentication timeout if
@@ -432,7 +430,7 @@
*
* Cannot be hardware-enforced.
*/
- ALLOW_WHILE_ON_BODY = (7 << 28) /* TagType:BOOL */ | 506,
+ ALLOW_WHILE_ON_BODY = TagType.BOOL | 506,
/**
* TRUSTED_USER_PRESENCE_REQUIRED is an optional feature that specifies that this key must be
@@ -479,7 +477,7 @@
*
* Must be hardware-enforced.
*/
- TRUSTED_USER_PRESENCE_REQUIRED = (7 << 28) /* TagType:BOOL */ | 507,
+ TRUSTED_USER_PRESENCE_REQUIRED = TagType.BOOL | 507,
/**
* Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and
@@ -493,7 +491,7 @@
*
* Must be hardware-enforced.
*/
- TRUSTED_CONFIRMATION_REQUIRED = (7 << 28) /* TagType:BOOL */ | 508,
+ TRUSTED_CONFIRMATION_REQUIRED = TagType.BOOL | 508,
/**
* Tag::UNLOCKED_DEVICE_REQUIRED specifies that the key may only be used when the device is
@@ -503,7 +501,7 @@
* Must be hardware-enforced (but is also keystore-enforced on a per-user basis: see the
* deviceLocked() documentation).
*/
- UNLOCKED_DEVICE_REQUIRED = (7 << 28) /* TagType:BOOL */ | 509,
+ UNLOCKED_DEVICE_REQUIRED = TagType.BOOL | 509,
/**
* Tag::APPLICATION_ID. When provided to generateKey or importKey, this tag specifies data
@@ -519,7 +517,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- APPLICATION_ID = (9 << 28) /* TagType:BYTES */ | 601,
+ APPLICATION_ID = TagType.BYTES | 601,
/*
* Semantically unenforceable tags, either because they have no specific meaning or because
@@ -540,7 +538,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- APPLICATION_DATA = (9 << 28) /* TagType:BYTES */ | 700,
+ APPLICATION_DATA = TagType.BYTES | 700,
/**
* Tag::CREATION_DATETIME specifies the date and time the key was created, in milliseconds since
@@ -548,7 +546,7 @@
*
* Must be in the software-enforced list, if provided.
*/
- CREATION_DATETIME = (6 << 28) /* TagType:DATE */ | 701,
+ CREATION_DATETIME = TagType.DATE | 701,
/**
* Tag::ORIGIN specifies where the key was created, if known. This tag must not be specified
@@ -557,7 +555,7 @@
*
* Must be hardware-enforced.
*/
- ORIGIN = (1 << 28) /* TagType:ENUM */ | 702,
+ ORIGIN = TagType.ENUM | 702,
// 703 is unused.
@@ -569,7 +567,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ROOT_OF_TRUST = (9 << 28) /* TagType:BYTES */ | 704,
+ ROOT_OF_TRUST = TagType.BYTES | 704,
/**
* Tag::OS_VERSION specifies the system OS version with which the key may be used. This tag is
@@ -592,7 +590,7 @@
*
* Must be hardware-enforced.
*/
- OS_VERSION = (3 << 28) /* TagType:UINT */ | 705,
+ OS_VERSION = TagType.UINT | 705,
/**
* Tag::OS_PATCHLEVEL specifies the system security patch level with which the key may be used.
@@ -613,7 +611,7 @@
*
* Must be hardware-enforced.
*/
- OS_PATCHLEVEL = (3 << 28) /* TagType:UINT */ | 706,
+ OS_PATCHLEVEL = TagType.UINT | 706,
/**
* Tag::UNIQUE_ID specifies a unique, time-based identifier. This tag is never provided to or
@@ -648,7 +646,7 @@
*
* Must be hardware-enforced.
*/
- UNIQUE_ID = (9 << 28) /* TagType:BYTES */ | 707,
+ UNIQUE_ID = TagType.BYTES | 707,
/**
* Tag::ATTESTATION_CHALLENGE is used to deliver a "challenge" value to the attested key
@@ -657,7 +655,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_CHALLENGE = (9 << 28) /* TagType:BYTES */ | 708,
+ ATTESTATION_CHALLENGE = TagType.BYTES | 708,
/**
* Tag::ATTESTATION_APPLICATION_ID identifies the set of applications which may use a key, used
@@ -683,7 +681,7 @@
*
* Cannot be hardware-enforced.
*/
- ATTESTATION_APPLICATION_ID = (9 << 28) /* TagType:BYTES */ | 709,
+ ATTESTATION_APPLICATION_ID = TagType.BYTES | 709,
/**
* Tag::ATTESTATION_ID_BRAND provides the device's brand name, as returned by Build.BRAND in
@@ -696,7 +694,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_ID_BRAND = (9 << 28) /* TagType:BYTES */ | 710,
+ ATTESTATION_ID_BRAND = TagType.BYTES | 710,
/**
* Tag::ATTESTATION_ID_DEVICE provides the device's device name, as returned by Build.DEVICE in
@@ -709,7 +707,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_ID_DEVICE = (9 << 28) /* TagType:BYTES */ | 711,
+ ATTESTATION_ID_DEVICE = TagType.BYTES | 711,
/**
* Tag::ATTESTATION_ID_PRODUCT provides the device's product name, as returned by Build.PRODUCT
@@ -722,7 +720,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_ID_PRODUCT = (9 << 28) /* TagType:BYTES */ | 712,
+ ATTESTATION_ID_PRODUCT = TagType.BYTES | 712,
/**
* Tag::ATTESTATION_ID_SERIAL the device's serial number. This field must be set only when
@@ -734,7 +732,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_ID_SERIAL = (9 << 28) /* TagType:BYTES */ | 713,
+ ATTESTATION_ID_SERIAL = TagType.BYTES | 713,
/**
* Tag::ATTESTATION_ID_IMEI provides the IMEIs for all radios on the device to attested key
@@ -747,7 +745,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_ID_IMEI = (9 << 28) /* TagType:BYTES */ | 714,
+ ATTESTATION_ID_IMEI = TagType.BYTES | 714,
/**
* Tag::ATTESTATION_ID_MEID provides the MEIDs for all radios on the device to attested key
@@ -760,7 +758,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_ID_MEID = (9 << 28) /* TagType:BYTES */ | 715,
+ ATTESTATION_ID_MEID = TagType.BYTES | 715,
/**
* Tag::ATTESTATION_ID_MANUFACTURER provides the device's manufacturer name, as returned by
@@ -773,7 +771,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_ID_MANUFACTURER = (9 << 28) /* TagType:BYTES */ | 716,
+ ATTESTATION_ID_MANUFACTURER = TagType.BYTES | 716,
/**
* Tag::ATTESTATION_ID_MODEL provides the device's model name, as returned by Build.MODEL in
@@ -786,7 +784,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- ATTESTATION_ID_MODEL = (9 << 28) /* TagType:BYTES */ | 717,
+ ATTESTATION_ID_MODEL = TagType.BYTES | 717,
/**
* Tag::VENDOR_PATCHLEVEL specifies the vendor image security patch level with which the key may
@@ -808,7 +806,7 @@
*
* Must be hardware-enforced.
*/
- VENDOR_PATCHLEVEL = (3 << 28) /* TagType:UINT */ | 718,
+ VENDOR_PATCHLEVEL = TagType.UINT | 718,
/**
* Tag::BOOT_PATCHLEVEL specifies the boot image (kernel) security patch level with which the
@@ -828,7 +826,7 @@
*
* Must be hardware-enforced.
*/
- BOOT_PATCHLEVEL = (3 << 28) /* TagType:UINT */ | 719,
+ BOOT_PATCHLEVEL = TagType.UINT | 719,
/**
* DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attested key generation/import
@@ -854,7 +852,7 @@
* IKeyMintDevice implementations that support device-unique attestation MUST add the
* DEVICE_UNIQUE_ATTESTATION tag to device-unique attestations.
*/
- DEVICE_UNIQUE_ATTESTATION = (7 << 28) /* TagType:BOOL */ | 720,
+ DEVICE_UNIQUE_ATTESTATION = TagType.BOOL | 720,
/**
* IDENTITY_CREDENTIAL_KEY is never used by IKeyMintDevice, is not a valid argument to key
@@ -862,7 +860,7 @@
* attestation. It is used in attestations produced by the IIdentityCredential HAL when that
* HAL attests to Credential Keys. IIdentityCredential produces KeyMint-style attestations.
*/
- IDENTITY_CREDENTIAL_KEY = (7 << 28) /* TagType:BOOL */ | 721,
+ IDENTITY_CREDENTIAL_KEY = TagType.BOOL | 721,
/**
* To prevent keys from being compromised if an attacker acquires read access to system / kernel
@@ -880,12 +878,13 @@
* ErrorCode::INVALID_OPERATION is returned when a key with Tag::STORAGE_KEY is provided to
* begin().
*/
- STORAGE_KEY = (7 << 28) /* TagType:BOOL */ | 722,
+ STORAGE_KEY = TagType.BOOL | 722,
/**
- * TODO: Delete when keystore1 is deleted.
+ * OBSOLETE: Do not use. See IKeyMintOperation.updateAad instead.
+ * TODO(b/191738660): Remove in KeyMint v2.
*/
- ASSOCIATED_DATA = (9 << 28) /* TagType:BYTES */ | 1000,
+ ASSOCIATED_DATA = TagType.BYTES | 1000,
/**
* Tag::NONCE is used to provide or return a nonce or Initialization Vector (IV) for AES-GCM,
@@ -900,7 +899,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- NONCE = (9 << 28) /* TagType:BYTES */ | 1001,
+ NONCE = TagType.BYTES | 1001,
/**
* Tag::MAC_LENGTH provides the requested length of a MAC or GCM authentication tag, in bits.
@@ -911,7 +910,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- MAC_LENGTH = (3 << 28) /* TagType:UINT */ | 1003,
+ MAC_LENGTH = TagType.UINT | 1003,
/**
* Tag::RESET_SINCE_ID_ROTATION specifies whether the device has been factory reset since the
@@ -919,7 +918,7 @@
*
* Must never appear in KeyCharacteristics.
*/
- RESET_SINCE_ID_ROTATION = (7 << 28) /* TagType:BOOL */ | 1004,
+ RESET_SINCE_ID_ROTATION = TagType.BOOL | 1004,
/**
* OBSOLETE: Do not use. See the authToken parameter for IKeyMintDevice::begin and for
@@ -927,7 +926,7 @@
*
* TODO(b/191738660): Delete when keystore1 is deleted.
*/
- CONFIRMATION_TOKEN = (9 << 28) /* TagType:BYTES */ | 1005,
+ CONFIRMATION_TOKEN = TagType.BYTES | 1005,
/**
* Tag::CERTIFICATE_SERIAL specifies the serial number to be assigned to the attestation
@@ -935,7 +934,7 @@
* keyMint in the attestation parameters during generateKey() and importKey(). If not provided,
* the serial shall default to 1.
*/
- CERTIFICATE_SERIAL = (8 << 28) /* TagType:BIGNUM */ | 1006,
+ CERTIFICATE_SERIAL = TagType.BIGNUM | 1006,
/**
* Tag::CERTIFICATE_SUBJECT the certificate subject. The value is a DER encoded X509 NAME.
@@ -943,7 +942,7 @@
* during generateKey and importKey. If not provided the subject name shall default to
* CN="Android Keystore Key".
*/
- CERTIFICATE_SUBJECT = (9 << 28) /* TagType:BYTES */ | 1007,
+ CERTIFICATE_SUBJECT = TagType.BYTES | 1007,
/**
* Tag::CERTIFICATE_NOT_BEFORE the beginning of the validity of the certificate in UNIX epoch
@@ -951,7 +950,7 @@
* certificates. ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if
* this tag is not provided to generateKey or importKey.
*/
- CERTIFICATE_NOT_BEFORE = (6 << 28) /* TagType:DATE */ | 1008,
+ CERTIFICATE_NOT_BEFORE = TagType.DATE | 1008,
/**
* Tag::CERTIFICATE_NOT_AFTER the end of the validity of the certificate in UNIX epoch time in
@@ -959,7 +958,7 @@
* ErrorCode::MISSING_NOT_AFTER must be returned if this tag is not provided to generateKey or
* importKey.
*/
- CERTIFICATE_NOT_AFTER = (6 << 28) /* TagType:DATE */ | 1009,
+ CERTIFICATE_NOT_AFTER = TagType.DATE | 1009,
/**
* Tag::MAX_BOOT_LEVEL specifies a maximum boot level at which a key should function.
@@ -970,5 +969,5 @@
*
* Cannot be hardware enforced in this version.
*/
- MAX_BOOT_LEVEL = (3 << 28) /* TagType:UINT */ | 1010,
+ MAX_BOOT_LEVEL = TagType.UINT | 1010,
}
diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc
index 061689d..bc6bb6a 100644
--- a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc
+++ b/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc
@@ -4,6 +4,7 @@
interface android.hardware.wifi@1.2::IWifi default
interface android.hardware.wifi@1.3::IWifi default
interface android.hardware.wifi@1.4::IWifi default
+ interface android.hardware.wifi@1.5::IWifi default
oneshot
disabled
class hal
diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.5/default/wifi_ap_iface.cpp
index b438a4a..1ae7905 100644
--- a/wifi/1.5/default/wifi_ap_iface.cpp
+++ b/wifi/1.5/default/wifi_ap_iface.cpp
@@ -136,24 +136,25 @@
WifiStatus WifiApIface::setMacAddressInternal(
const std::array<uint8_t, 6>& mac) {
- bool status;
// Support random MAC up to 2 interfaces
if (instances_.size() == 2) {
int rbyte = 1;
for (auto const& intf : instances_) {
std::array<uint8_t, 6> rmac = mac;
- // reverse the bits to avoid clision
+ // reverse the bits to avoid collision
rmac[rbyte] = 0xff - rmac[rbyte];
- status = iface_util_.lock()->setMacAddress(intf, rmac);
- if (!status) {
+ if (!iface_util_.lock()->setMacAddress(intf, rmac)) {
LOG(INFO) << "Failed to set random mac address on " << intf;
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
}
rbyte++;
}
- } else {
- status = iface_util_.lock()->setMacAddress(ifname_, mac);
}
- if (!status) {
+ // It also needs to set mac address for bridged interface, otherwise the mac
+ // address of bridged interface will be changed after one of instance
+ // down.
+ if (!iface_util_.lock()->setMacAddress(ifname_, mac)) {
+ LOG(ERROR) << "Fail to config MAC for interface " << ifname_;
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
}
return createWifiStatus(WifiStatusCode::SUCCESS);
@@ -181,6 +182,18 @@
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
}
}
+ // It needs to set mac address for bridged interface, otherwise the mac
+ // address of the bridged interface will be changed after one of the
+ // instance down. Thus we are generating a random MAC address for the
+ // bridged interface even if we got the request to reset the Factory
+ // MAC. Since the bridged interface is an internal interface for the
+ // operation of bpf and others networking operation.
+ if (!iface_util_.lock()->setMacAddress(
+ ifname_, iface_util_.lock()->createRandomMacAddress())) {
+ LOG(ERROR) << "Fail to config MAC for bridged interface "
+ << ifname_;
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
} else {
getMacResult = getFactoryMacAddressInternal(ifname_);
LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_;
diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.5/default/wifi_iface_util.cpp
index d1434e3..7bf830b 100644
--- a/wifi/1.5/default/wifi_iface_util.cpp
+++ b/wifi/1.5/default/wifi_iface_util.cpp
@@ -86,9 +86,9 @@
event_handlers.on_state_toggle_off_on(iface_name);
}
if (!success) {
- LOG(ERROR) << "SetMacAddress failed.";
+ LOG(ERROR) << "SetMacAddress failed on " << iface_name;
} else {
- LOG(DEBUG) << "SetMacAddress succeeded.";
+ LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name;
}
return success;
}
diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.5/default/wifi_iface_util.h
index b449077..544f575 100644
--- a/wifi/1.5/default/wifi_iface_util.h
+++ b/wifi/1.5/default/wifi_iface_util.h
@@ -71,10 +71,10 @@
virtual bool removeIfaceFromBridge(const std::string& br_name,
const std::string& if_name);
+ // Get a random MAC address.
+ virtual std::array<uint8_t, 6> createRandomMacAddress();
private:
- std::array<uint8_t, 6> createRandomMacAddress();
-
std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;