Authenticate nanoapps loaded on FreeRTOS

Adds logic needed to ensure nanoapps are signed properly before loading
them onto a device. At the moment, this logic has no effect since
nanoapps aren't signed yet.

Bug: 158713869
Test: Load CHRE and verify an authentication response is received

Change-Id: I60d36ddf80a180bb78a47c6b47357959f29e8dee
diff --git a/platform/freertos/include/chre/target_platform/condition_variable_base.h b/platform/freertos/include/chre/target_platform/condition_variable_base.h
index 382954e..d290c62 100644
--- a/platform/freertos/include/chre/target_platform/condition_variable_base.h
+++ b/platform/freertos/include/chre/target_platform/condition_variable_base.h
@@ -47,6 +47,13 @@
  *   is an extra iteration of the while-empty-queue loop.
  */
 class ConditionVariableBase {
+ public:
+  /**
+   * While in an interrupt context, unblock one thread that is waiting on this
+   * condition variable.
+   */
+  void notify_one_from_isr();
+
  protected:
   // Since, per CHRE specification, only one thread is ever
   // going to be blocked on this condition variable, all we
diff --git a/platform/freertos/include/chre/target_platform/condition_variable_impl.h b/platform/freertos/include/chre/target_platform/condition_variable_impl.h
index 296738e..54adf21 100644
--- a/platform/freertos/include/chre/target_platform/condition_variable_impl.h
+++ b/platform/freertos/include/chre/target_platform/condition_variable_impl.h
@@ -72,6 +72,12 @@
   return !mTimedOut;
 }
 
+inline void ConditionVariableBase::notify_one_from_isr() {
+  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+  xSemaphoreGiveFromISR(mCvSemaphoreHandle, &xHigherPriorityTaskWoken);
+  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
+}
+
 }  // namespace chre
 
 #endif  // CHRE_PLATFORM_FREERTOS_CONDITION_VARIABLE_IMPL_H_
diff --git a/platform/freertos/platform_nanoapp.cc b/platform/freertos/platform_nanoapp.cc
index 80fbf17..180c879 100644
--- a/platform/freertos/platform_nanoapp.cc
+++ b/platform/freertos/platform_nanoapp.cc
@@ -21,6 +21,7 @@
 
 #include "chre/platform/assert.h"
 #include "chre/platform/log.h"
+#include "chre/platform/shared/authentication.h"
 #include "chre/platform/shared/memory.h"
 #include "chre/platform/shared/nanoapp_dso_util.h"
 #include "chre/platform/shared/nanoapp_loader.h"
@@ -248,8 +249,19 @@
   if (mIsStatic) {
     success = true;
   } else if (mAppBinary != nullptr) {
+    //! The true start of the binary will be after the authentication header.
+    //! Use the returned value from authenticateBinary to ensure dlopenbuf has
+    //! the starting address to a valid ELF.
+    void *binaryStart = mAppBinary;
+
+    // TODO(158770259): Enforce this and make the log message and error once all
+    // nanoapp binaries are signed.
+    if (!authenticateBinary(mAppBinary, &binaryStart)) {
+      LOGV("Unable to authenticate 0x%" PRIx32 " not stopping loading for now",
+           mExpectedAppId);
+    }
     if (mDsoHandle == nullptr) {
-      mDsoHandle = dlopenbuf(mAppBinary, mExpectedTcmCapable);
+      mDsoHandle = dlopenbuf(binaryStart, mExpectedTcmCapable);
       success = verifyNanoappInfo();
     } else {
       LOGE("Trying to reopen an existing buffer");
diff --git a/platform/shared/include/chre/platform/shared/authentication.h b/platform/shared/include/chre/platform/shared/authentication.h
new file mode 100644
index 0000000..6409b47
--- /dev/null
+++ b/platform/shared/include/chre/platform/shared/authentication.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef CHRE_PLATFORM_SHARED_AUTHENTICATION_H_
+#define CHRE_PLATFORM_SHARED_AUTHENTICATION_H_
+
+namespace chre {
+
+/**
+ * Authenticates the signature of the provided binary. If not provided
+ * elsewhere by the platform, this method must ensure that nanoapps are signed
+ * appropriately and no corruption has occurred to the binary prior to being
+ * loaded. If this method succeeds, CHRE will assume the binary has the same
+ * execution privileges as the core framework itself.
+ *
+ * @param binary Pointer to the binary that should be authenticated.
+ * @param realBinaryStart A non-null pointer that, if this method succeeds, must
+ *     be filled with the starting address of the raw binary after any headers
+ *     used by the authentication code. This will be passed to the dynamic
+ *     loader which will assume the starting address is a valid ELF binary.
+ * @return True if the binary passed authentication.
+ */
+bool authenticateBinary(void *binary, void **realBinaryStart);
+
+}  // namespace chre
+
+#endif  // CHRE_PLATFORM_SHARED_AUTHENTICATION_H_