summaryrefslogtreecommitdiff
path: root/rebootescrow
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2019-12-04 07:54:20 -0800
committerKenny Root <kroot@google.com>2019-12-19 09:59:40 -0800
commitd0c4f2bb404e87c96f83a0ef75c76145a1af6161 (patch)
tree8624a04f8b5e4c14160973ced11747d116d328bf /rebootescrow
parenta0a12cfcf216c7ba3ee43ec86e81e708a8db2519 (diff)
Resume on Reboot default implementation
A default implementation of the RebootEscrow HAL which relies on RAM retention to keep a key around during a reboot to apply an OTA. This should work on devices that use a "warm reboot" and most likely will work on devices that use a "cold reboot" as well. DRAM will retain information for several seconds depending on the temperature and other factors. This is enough to survive a reboot. With the Hadamard code used in this change for error recovery, many errors can be recovered. Bug: 63928581 Test: make Test: atest VtsHalRebootEscrowTargetTest Change-Id: Ib8db7888d64fee8d827d7c06892b9a1f2af87add
Diffstat (limited to 'rebootescrow')
-rw-r--r--rebootescrow/aidl/default/Android.bp41
-rw-r--r--rebootescrow/aidl/default/RebootEscrow.cpp75
-rw-r--r--rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h36
-rw-r--r--rebootescrow/aidl/default/rebootescrow-default.rc9
-rw-r--r--rebootescrow/aidl/default/rebootescrow-default.xml6
-rw-r--r--rebootescrow/aidl/default/service.cpp35
6 files changed, 202 insertions, 0 deletions
diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp
index eb228ad827..c8cbf48834 100644
--- a/rebootescrow/aidl/default/Android.bp
+++ b/rebootescrow/aidl/default/Android.bp
@@ -15,6 +15,47 @@
//
cc_library_static {
+ name: "librebootescrowdefaultimpl",
+ vendor: true,
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "vintf-rebootescrow-ndk_platform",
+ ],
+ export_include_dirs: ["include"],
+ srcs: [
+ "RebootEscrow.cpp",
+ ],
+ visibility: [
+ ":__subpackages__",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.rebootescrow-service.default",
+ init_rc: ["rebootescrow-default.rc"],
+ relative_install_path: "hw",
+ vintf_fragments: ["rebootescrow-default.xml"],
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "vintf-rebootescrow-ndk_platform",
+ ],
+ static_libs: [
+ "libhadamardutils",
+ "librebootescrowdefaultimpl",
+ ],
+}
+
+cc_library_static {
name: "libhadamardutils",
vendor_available: true,
host_supported: true,
diff --git a/rebootescrow/aidl/default/RebootEscrow.cpp b/rebootescrow/aidl/default/RebootEscrow.cpp
new file mode 100644
index 0000000000..94d09010d9
--- /dev/null
+++ b/rebootescrow/aidl/default/RebootEscrow.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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 <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+
+#include "HadamardUtils.h"
+#include "rebootescrow-impl/RebootEscrow.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace rebootescrow {
+
+using ::android::base::unique_fd;
+
+ndk::ScopedAStatus RebootEscrow::storeKey(const std::vector<int8_t>& kek) {
+ int rawFd = TEMP_FAILURE_RETRY(::open(REBOOT_ESCROW_DEVICE, O_WRONLY | O_NOFOLLOW | O_CLOEXEC));
+ unique_fd fd(rawFd);
+ if (fd.get() < 0) {
+ LOG(WARNING) << "Could not open reboot escrow device";
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+ }
+
+ std::vector<uint8_t> ukek(kek.begin(), kek.end());
+ auto encoded = hadamard::EncodeKey(ukek);
+
+ if (!::android::base::WriteFully(fd, encoded.data(), encoded.size())) {
+ LOG(WARNING) << "Could not write data fully to character device";
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RebootEscrow::retrieveKey(std::vector<int8_t>* _aidl_return) {
+ int rawFd = TEMP_FAILURE_RETRY(::open(REBOOT_ESCROW_DEVICE, O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
+ unique_fd fd(rawFd);
+ if (fd.get() < 0) {
+ LOG(WARNING) << "Could not open reboot escrow device";
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+ }
+
+ std::string encodedString;
+ if (!::android::base::ReadFdToString(fd, &encodedString)) {
+ LOG(WARNING) << "Could not read device to string";
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+ }
+
+ std::vector<uint8_t> encodedBytes(encodedString.begin(), encodedString.end());
+ auto keyBytes = hadamard::DecodeKey(encodedBytes);
+
+ std::vector<int8_t> signedKeyBytes(keyBytes.begin(), keyBytes.end());
+ *_aidl_return = signedKeyBytes;
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace rebootescrow
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h b/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h
new file mode 100644
index 0000000000..1ed73978d9
--- /dev/null
+++ b/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/rebootescrow/BnRebootEscrow.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace rebootescrow {
+
+static const char* REBOOT_ESCROW_DEVICE = "/dev/access-kregistry";
+
+class RebootEscrow : public BnRebootEscrow {
+ ndk::ScopedAStatus storeKey(const std::vector<int8_t>& kek) override;
+ ndk::ScopedAStatus retrieveKey(std::vector<int8_t>* _aidl_return) override;
+};
+
+} // namespace rebootescrow
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/rebootescrow/aidl/default/rebootescrow-default.rc b/rebootescrow/aidl/default/rebootescrow-default.rc
new file mode 100644
index 0000000000..e7a9cfcb70
--- /dev/null
+++ b/rebootescrow/aidl/default/rebootescrow-default.rc
@@ -0,0 +1,9 @@
+service vendor.rebootescrow-default /vendor/bin/hw/android.hardware.rebootescrow-service.default
+ interface aidl android.hardware.rebootescrow.IRebootEscrow/default
+ class hal
+ user system
+ group system
+
+on boot
+ chmod 770 /dev/access-kregistry
+ chown system system /dev/access-kregistry
diff --git a/rebootescrow/aidl/default/rebootescrow-default.xml b/rebootescrow/aidl/default/rebootescrow-default.xml
new file mode 100644
index 0000000000..0499fccdf3
--- /dev/null
+++ b/rebootescrow/aidl/default/rebootescrow-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.rebootescrow</name>
+ <fqname>IRebootEscrow/default</fqname>
+ </hal>
+</manifest>
diff --git a/rebootescrow/aidl/default/service.cpp b/rebootescrow/aidl/default/service.cpp
new file mode 100644
index 0000000000..bd2378e513
--- /dev/null
+++ b/rebootescrow/aidl/default/service.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "rebootescrow-impl/RebootEscrow.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::rebootescrow::RebootEscrow;
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ auto re = ndk::SharedRefBase::make<RebootEscrow>();
+ const std::string instance = std::string() + RebootEscrow::descriptor + "/default";
+ binder_status_t status = AServiceManager_addService(re->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE;
+}