diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index f5acdd441e..1e3f74332a 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -388,6 +388,13 @@ default + + android.hardware.rebootescrow + + IRebootEscrow + default + + android.hardware.secure_element 1.0 diff --git a/rebootescrow/aidl/Android.bp b/rebootescrow/aidl/Android.bp new file mode 100644 index 0000000000..7bc8d6ff3f --- /dev/null +++ b/rebootescrow/aidl/Android.bp @@ -0,0 +1,18 @@ +aidl_interface { + name: "vintf-rebootescrow", + vendor_available: true, + srcs: [ + "android/hardware/rebootescrow/IRebootEscrow.aidl", + ], + stability: "vintf", + backend: { + java: { + platform_apis: true, + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} diff --git a/rebootescrow/aidl/android/hardware/rebootescrow/IRebootEscrow.aidl b/rebootescrow/aidl/android/hardware/rebootescrow/IRebootEscrow.aidl new file mode 100644 index 0000000000..edc695d301 --- /dev/null +++ b/rebootescrow/aidl/android/hardware/rebootescrow/IRebootEscrow.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.rebootescrow; + +/** + * This HAL defines the interface to the device-specific implementation + * of retaining a secret to unlock the Synthetic Password stored during + * a reboot to perform an OTA update. The implementation of this interface + * should never store the key on any non-volatile medium. The key should be + * overwritten with zeroes when destroyKey() is called. All care should be given + * to provide the shortest lifetime for the storage of the key in volatile and + * erasable storage. + * + * This HAL is optional so does not require an implementation on device. + */ +@VintfStability +interface IRebootEscrow { + /** + * Store the key for reboot. + */ + void storeKey(in byte[] kek); + + /** + * Retrieve the possible keys. If the implementation is probabalistic, it + * should return the keys in order from most-probable to least-probable. + * There is not a hard limit to the number of keys, but it is suggested to + * keep the number of key possibilities less than 32. + */ + byte[] retrieveKey(); +} diff --git a/rebootescrow/aidl/vts/functional/Android.bp b/rebootescrow/aidl/vts/functional/Android.bp new file mode 100644 index 0000000000..dadf2509d8 --- /dev/null +++ b/rebootescrow/aidl/vts/functional/Android.bp @@ -0,0 +1,34 @@ +// +// Copyright (C) 2019 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: "VtsHalRebootEscrowTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalRebootEscrowTargetTest.cpp"], + shared_libs: [ + "libbinder", + ], + static_libs: [ + "vintf-rebootescrow-cpp", + ], + test_suites: [ + "vts-core", + ], + require_root: true, +} diff --git a/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp b/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp new file mode 100644 index 0000000000..f69cf877ad --- /dev/null +++ b/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2019 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 +#include + +#include + +#include +#include + +using android::sp; +using android::String16; +using android::hardware::rebootescrow::IRebootEscrow; + +/** + * This tests that the key can be written, read, and removed. It does not test + * that the key survives a reboot. That needs a host-based test. + * + * atest VtsHalRebootEscrowV1_0TargetTest + */ +class RebootEscrowAidlTest : public testing::TestWithParam { + public: + virtual void SetUp() override { + rebootescrow = android::waitForDeclaredService(String16(GetParam().c_str())); + ASSERT_NE(rebootescrow, nullptr); + } + + sp rebootescrow; + + std::vector KEY_1{ + 0xA5, 0x00, 0xFF, 0x01, 0xA5, 0x5a, 0xAA, 0x55, 0x00, 0xD3, 0x2A, + 0x8C, 0x2E, 0x83, 0x0E, 0x65, 0x9E, 0x8D, 0xC6, 0xAC, 0x1E, 0x83, + 0x21, 0xB3, 0x95, 0x02, 0x89, 0x64, 0x64, 0x92, 0x12, 0x1F, + }; + std::vector KEY_2{ + 0xFF, 0x00, 0x00, 0xAA, 0x5A, 0x19, 0x20, 0x71, 0x9F, 0xFB, 0xDA, + 0xB6, 0x2D, 0x06, 0xD5, 0x49, 0x7E, 0xEF, 0x63, 0xAC, 0x18, 0xFF, + 0x5A, 0xA3, 0x40, 0xBB, 0x64, 0xFA, 0x67, 0xC1, 0x10, 0x18, + }; + std::vector EMPTY_KEY{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; +}; + +TEST_P(RebootEscrowAidlTest, StoreAndRetrieve_Success) { + ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk()); + + std::vector actualKey; + ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk()); + EXPECT_EQ(actualKey, KEY_1); +} + +TEST_P(RebootEscrowAidlTest, StoreAndRetrieve_SecondRetrieveSucceeds) { + ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk()); + + std::vector actualKey; + ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk()); + EXPECT_EQ(actualKey, KEY_1); + + ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk()); + EXPECT_EQ(actualKey, KEY_1); +} + +TEST_P(RebootEscrowAidlTest, StoreTwiceOverwrites_Success) { + ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk()); + ASSERT_TRUE(rebootescrow->storeKey(KEY_2).isOk()); + + std::vector actualKey; + ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk()); + EXPECT_EQ(actualKey, KEY_2); +} + +TEST_P(RebootEscrowAidlTest, StoreEmpty_AfterGetEmptyKey_Success) { + rebootescrow->storeKey(KEY_1); + rebootescrow->storeKey(EMPTY_KEY); + + std::vector actualKey; + ASSERT_TRUE(rebootescrow->retrieveKey(&actualKey).isOk()); + EXPECT_EQ(actualKey, EMPTY_KEY); +} + +INSTANTIATE_TEST_SUITE_P( + RebootEscrow, RebootEscrowAidlTest, + testing::ValuesIn(android::getAidlHalInstanceNames(IRebootEscrow::descriptor)), + android::PrintInstanceNameToString);