Merge "Run BoringSSL self test during startup"
diff --git a/init/Android.bp b/init/Android.bp
index d82ec66..ea66ac6 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -71,6 +71,7 @@
         "libbinder",
         "libbootloader_message",
         "libcutils",
+        "libcrypto",
         "libdl",
         "libext4_utils",
         "libfs_mgr",
@@ -93,6 +94,7 @@
         "action.cpp",
         "action_manager.cpp",
         "action_parser.cpp",
+        "boringssl_self_test.cpp",
         "bootchart.cpp",
         "builtins.cpp",
         "capabilities.cpp",
diff --git a/init/boringssl_self_test.cpp b/init/boringssl_self_test.cpp
new file mode 100644
index 0000000..0408d30
--- /dev/null
+++ b/init/boringssl_self_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 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 "boringssl_self_test.h"
+
+#include <android-base/logging.h>
+#include <cutils/android_reboot.h>
+#include <openssl/crypto.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace android {
+namespace init {
+
+Result<Success> StartBoringSslSelfTest(const BuiltinArguments&) {
+    pid_t id = fork();
+
+    if (id == 0) {
+        if (BORINGSSL_self_test() != 1) {
+            LOG(INFO) << "BoringSSL crypto self tests failed";
+
+            // This check has failed, so the device should refuse
+            // to boot. Rebooting to bootloader to wait for
+            // further action from the user.
+
+            int result = android_reboot(ANDROID_RB_RESTART2, 0,
+                                        "bootloader,boringssl-self-check-failed");
+            if (result != 0) {
+                LOG(ERROR) << "Failed to reboot into bootloader";
+            }
+        }
+
+        _exit(0);
+    } else if (id == -1) {
+        // Failed to fork, so cannot run the test. Refuse to continue.
+        PLOG(FATAL) << "Failed to fork for BoringSSL self test";
+    }
+
+    return Success();
+}
+
+}  // namespace init
+}  // namespace android
diff --git a/init/boringssl_self_test.h b/init/boringssl_self_test.h
new file mode 100644
index 0000000..b21fc78
--- /dev/null
+++ b/init/boringssl_self_test.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 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 "builtin_arguments.h"
+#include "result.h"
+
+namespace android {
+namespace init {
+
+Result<Success> StartBoringSslSelfTest(const BuiltinArguments&);
+
+}  // namespace init
+}  // namespace android
diff --git a/init/init.cpp b/init/init.cpp
index 39c1832..dc46a82 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -49,6 +49,7 @@
 #endif
 
 #include "action_parser.h"
+#include "boringssl_self_test.h"
 #include "epoll.h"
 #include "first_stage_mount.h"
 #include "import_parser.h"
@@ -697,6 +698,9 @@
     // Trigger all the boot actions to get us started.
     am.QueueEventTrigger("init");
 
+    // Starting the BoringSSL self test, for NIAP certification compliance.
+    am.QueueBuiltinAction(StartBoringSslSelfTest, "StartBoringSslSelfTest");
+
     // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
     // wasn't ready immediately after wait_for_coldboot_done
     am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");