diff options
author | Chirag Pathak <pathakc@google.com> | 2021-01-25 21:37:06 +0000 |
---|---|---|
committer | Chirag Pathak <pathakc@google.com> | 2021-02-10 18:48:34 +0000 |
commit | 8960aaefeaedd1a31b088c618d4dece7a0ca1cc6 (patch) | |
tree | a941b6366377790aee040c1d1e47221a57775974 /security/secureclock/aidl | |
parent | 9b2940dbcedefb91cb9f0457ba4e04262f931811 (diff) | |
download | platform_hardware_interfaces-8960aaefeaedd1a31b088c618d4dece7a0ca1cc6.tar.gz platform_hardware_interfaces-8960aaefeaedd1a31b088c618d4dece7a0ca1cc6.tar.bz2 platform_hardware_interfaces-8960aaefeaedd1a31b088c618d4dece7a0ca1cc6.zip |
The implementation of vts and default implementation to support ISecureClock and ISharedSecret AIDLs.
Test: atest VtsAidlSecureClockTargetTest, atest VtsAidlSharedSecretTargetTest
Bug: b/175136979, b/175141176
Change-Id: I4a0d25981d0172c0e2c8defc61b325eca6d6a029
Diffstat (limited to 'security/secureclock/aidl')
8 files changed, 321 insertions, 8 deletions
diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl index c16b312cda..377889716a 100644 --- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl @@ -1,4 +1,17 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2020 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. + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -20,5 +33,5 @@ package android.hardware.security.secureclock; @VintfStability interface ISecureClock { android.hardware.security.secureclock.TimeStampToken generateTimeStamp(in long challenge); - const String TIME_STAMP_MAC_LABEL = "Time Verification"; + const String TIME_STAMP_MAC_LABEL = "Auth Verification"; } diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl index 21eeb74519..00a8bb256d 100644 --- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl index f01fdc74c0..bebeb5cb9c 100644 --- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl index 7d416dda7a..577dd8f231 100644 --- a/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl +++ b/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl @@ -33,7 +33,7 @@ interface ISecureClock { * String used as context in the HMAC computation signing the generated time stamp. * See TimeStampToken.mac for details. */ - const String TIME_STAMP_MAC_LABEL = "Time Verification"; + const String TIME_STAMP_MAC_LABEL = "Auth Verification"; /** * Generates an authenticated timestamp. diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl index 3fb586078a..dd957325e9 100644 --- a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl +++ b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl @@ -39,18 +39,20 @@ parcelable TimeStampToken { * 32-byte HMAC-SHA256 of the above values, computed as: * * HMAC(H, - * ISecureClock.TIME_STAMP_MAC_LABEL || challenge || timestamp) + * ISecureClock.TIME_STAMP_MAC_LABEL || challenge || timestamp || securityLevel ) * * where: * * ``ISecureClock.TIME_STAMP_MAC_LABEL'' is a sting constant defined in ISecureClock.aidl. * - * ``H'' is the shared HMAC key (see computeSharedHmac() in ISharedHmacSecret). + * ``H'' is the shared HMAC key (see computeSharedHmac() in ISharedSecret). * * ``||'' represents concatenation * * The representation of challenge and timestamp is as 64-bit unsigned integers in big-endian - * order. securityLevel is represented as a 32-bit unsigned integer in big-endian order. + * order. SecurityLevel is represented as a 32-bit unsigned integer in big-endian order as + * described in android.hardware.security.keymint.SecurityLevel. It represents the security + * level of the secure clock environment. */ byte[] mac; } diff --git a/security/secureclock/aidl/vts/functional/Android.bp b/security/secureclock/aidl/vts/functional/Android.bp new file mode 100644 index 0000000000..30244eb137 --- /dev/null +++ b/security/secureclock/aidl/vts/functional/Android.bp @@ -0,0 +1,43 @@ +// +// Copyright (C) 2020 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. +// + +cc_test { + name: "VtsAidlSecureClockTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + cflags: [ + "-Wall", + "-Wextra", + ], + srcs: [ + "SecureClockAidlTest.cpp", + ], + shared_libs: [ + "libbinder_ndk", + "libcrypto", + "libkeymint", + ], + static_libs: [ + "android.hardware.security.keymint-unstable-ndk_platform", + "android.hardware.security.secureclock-unstable-ndk_platform", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/security/secureclock/aidl/vts/functional/AndroidTest.xml b/security/secureclock/aidl/vts/functional/AndroidTest.xml new file mode 100644 index 0000000000..4861c7c7af --- /dev/null +++ b/security/secureclock/aidl/vts/functional/AndroidTest.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 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 VtsAidlSecureClockTargetTest."> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-native" /> + + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> + <option name="cleanup" value="true" /> + <option name="push" + value="VtsAidlSecureClockTargetTest->/data/local/tmp/VtsAidlSecureClockTargetTest" /> + </target_preparer> + + <test class="com.android.tradefed.testtype.GTest" > + <option name="native-test-device-path" value="/data/local/tmp" /> + <option name="module-name" value="VtsAidlSecureClockTargetTest" /> + <option name="native-test-timeout" value="900000"/> + </test> +</configuration> diff --git a/security/secureclock/aidl/vts/functional/SecureClockAidlTest.cpp b/security/secureclock/aidl/vts/functional/SecureClockAidlTest.cpp new file mode 100644 index 0000000000..9ca1ee8af1 --- /dev/null +++ b/security/secureclock/aidl/vts/functional/SecureClockAidlTest.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "secureclock_test" +#include <android-base/logging.h> + +#include <aidl/Gtest.h> +#include <aidl/Vintf.h> +#include <aidl/android/hardware/security/keymint/ErrorCode.h> +#include <aidl/android/hardware/security/secureclock/ISecureClock.h> +#include <android/binder_manager.h> +#include <binder/ProcessState.h> +#include <gtest/gtest.h> +#include <vector> + +namespace aidl::android::hardware::security::secureclock::test { +using Status = ::ndk::ScopedAStatus; +using ::aidl::android::hardware::security::keymint::ErrorCode; +using ::std::shared_ptr; +using ::std::string; +using ::std::vector; + +class SecureClockAidlTest : public ::testing::TestWithParam<string> { + public: + struct TimestampTokenResult { + ErrorCode error; + TimeStampToken token; + }; + + TimestampTokenResult getTimestampToken(int64_t in_challenge) { + TimestampTokenResult result; + result.error = + GetReturnErrorCode(secureClock_->generateTimeStamp(in_challenge, &result.token)); + return result; + } + + uint64_t getTime() { + struct timespec timespec; + EXPECT_EQ(0, clock_gettime(CLOCK_BOOTTIME, ×pec)); + return timespec.tv_sec * 1000 + timespec.tv_nsec / 1000000; + } + + int sleep_ms(uint32_t milliseconds) { + struct timespec sleep_time = {static_cast<time_t>(milliseconds / 1000), + static_cast<long>(milliseconds % 1000) * 1000000}; + while (sleep_time.tv_sec || sleep_time.tv_nsec) { + if (nanosleep(&sleep_time /* to wait */, + &sleep_time /* remaining (on interrruption) */) == 0) { + sleep_time = {}; + } else { + if (errno != EINTR) return errno; + } + } + return 0; + } + + ErrorCode GetReturnErrorCode(const Status& result) { + if (result.isOk()) return ErrorCode::OK; + + if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) { + return static_cast<ErrorCode>(result.getServiceSpecificError()); + } + + return ErrorCode::UNKNOWN_ERROR; + } + + void InitializeSecureClock(std::shared_ptr<ISecureClock> secureClock) { + ASSERT_NE(secureClock, nullptr); + secureClock_ = secureClock; + } + + ISecureClock& secureClock() { return *secureClock_; } + + static vector<string> build_params() { + auto params = ::android::getAidlHalInstanceNames(ISecureClock::descriptor); + return params; + } + + void SetUp() override { + if (AServiceManager_isDeclared(GetParam().c_str())) { + ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str())); + InitializeSecureClock(ISecureClock::fromBinder(binder)); + } else { + InitializeSecureClock(nullptr); + } + } + + void TearDown() override {} + + private: + std::shared_ptr<ISecureClock> secureClock_; +}; + +/* + * The precise capabilities required to generate TimeStampToken will vary depending on the specific + * vendor implementations. The only thing we really can test is that tokens can be created by + * secureclock services, and that the timestamps increase as expected. + */ +TEST_P(SecureClockAidlTest, TestCreation) { + auto result1 = getTimestampToken(1 /* challenge */); + auto result1_time = getTime(); + EXPECT_EQ(ErrorCode::OK, result1.error); + EXPECT_EQ(1U, result1.token.challenge); + EXPECT_GT(result1.token.timestamp.milliSeconds, 0U); + + unsigned long time_to_sleep = 200; + sleep_ms(time_to_sleep); + + auto result2 = getTimestampToken(2 /* challenge */); + auto result2_time = getTime(); + EXPECT_EQ(ErrorCode::OK, result2.error); + EXPECT_EQ(2U, result2.token.challenge); + EXPECT_GT(result2.token.timestamp.milliSeconds, 0U); + + auto host_time_delta = result2_time - result1_time; + + EXPECT_GE(host_time_delta, time_to_sleep) + << "We slept for " << time_to_sleep << " ms, the clock must have advanced by that much"; + EXPECT_LE(host_time_delta, time_to_sleep + 100) + << "The getTimestampToken call took " << (host_time_delta - time_to_sleep) + << " ms? That's awful!"; + EXPECT_GE(result2.token.timestamp.milliSeconds, result1.token.timestamp.milliSeconds); + unsigned long km_time_delta = + result2.token.timestamp.milliSeconds - result1.token.timestamp.milliSeconds; + // 20 ms of slop just to avoid test flakiness. + EXPECT_LE(host_time_delta, km_time_delta + 20); + EXPECT_LE(km_time_delta, host_time_delta + 20); + ASSERT_EQ(result1.token.mac.size(), result2.token.mac.size()); + ASSERT_NE(0, + memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size())); +} + +/* + * Test that the mac changes when the time stamp changes. This is does not guarantee that the time + * stamp is included in the mac but on failure we know that it is not. Other than in the test + * case above we call getTimestampToken with the exact same set of parameters. + */ +TEST_P(SecureClockAidlTest, MacChangesOnChangingTimestamp) { + auto result1 = getTimestampToken(0 /* challenge */); + auto result1_time = getTime(); + EXPECT_EQ(ErrorCode::OK, result1.error); + EXPECT_EQ(0U, result1.token.challenge); + EXPECT_GT(result1.token.timestamp.milliSeconds, 0U); + + unsigned long time_to_sleep = 200; + sleep_ms(time_to_sleep); + + auto result2 = getTimestampToken(1 /* challenge */); + auto result2_time = getTime(); + EXPECT_EQ(ErrorCode::OK, result2.error); + EXPECT_EQ(1U, result2.token.challenge); + EXPECT_GT(result2.token.timestamp.milliSeconds, 0U); + + auto host_time_delta = result2_time - result1_time; + + EXPECT_GE(host_time_delta, time_to_sleep) + << "We slept for " << time_to_sleep << " ms, the clock must have advanced by that much"; + EXPECT_LE(host_time_delta, time_to_sleep + 100) + << "The getTimestampToken call took " << (host_time_delta - time_to_sleep) + << " ms? That's awful!"; + + EXPECT_GE(result2.token.timestamp.milliSeconds, result1.token.timestamp.milliSeconds); + unsigned long km_time_delta = + result2.token.timestamp.milliSeconds - result1.token.timestamp.milliSeconds; + + EXPECT_LE(host_time_delta, km_time_delta + 20); + EXPECT_LE(km_time_delta, host_time_delta + 20); + ASSERT_EQ(result1.token.mac.size(), result2.token.mac.size()); + ASSERT_NE(0, + memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size())); +} + +INSTANTIATE_TEST_SUITE_P(PerInstance, SecureClockAidlTest, + testing::ValuesIn(SecureClockAidlTest::build_params()), + ::android::PrintInstanceNameToString); +} // namespace aidl::android::hardware::security::secureclock::test + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}
\ No newline at end of file |