First working version of the confirmationui HAL service
This implementation does not provide any security guaranties.
* The input method (NotSoSecureInput) runs a crypto protocols that is
sufficiently secure IFF the end point is implemented on a trustworthy
secure input device. But since the endpoint is currently in the HAL
service itself this implementation is not secure.
* This implementation provides most of the functionality, but not the
secure UI infrastructure required to run Android Protected
Confirmation.
Bug: 146078942
Test: VtsHalConfirmationUIV1_0TargetTest
Change-Id: I14717b5fa4ef15db960cdd506b8c6fe5369aec8d
diff --git a/trusty/confirmationui/TrustyApp.cpp b/trusty/confirmationui/TrustyApp.cpp
new file mode 100644
index 0000000..e4c68f9
--- /dev/null
+++ b/trusty/confirmationui/TrustyApp.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+#include "TrustyApp.h"
+
+#include <android-base/logging.h>
+#include <sys/uio.h>
+#include <trusty/tipc.h>
+
+namespace android {
+namespace trusty {
+
+// 0x1000 is the message buffer size but we need to leave some space for a protocol header.
+// This assures that packets can always be read/written in one read/write operation.
+static constexpr const uint32_t kPacketSize = 0x1000 - 32;
+
+enum class PacketType : uint32_t {
+ SND,
+ RCV,
+ ACK,
+};
+
+struct PacketHeader {
+ PacketType type;
+ uint32_t remaining;
+};
+
+const char* toString(PacketType t) {
+ switch (t) {
+ case PacketType::SND:
+ return "SND";
+ case PacketType::RCV:
+ return "RCV";
+ case PacketType::ACK:
+ return "ACK";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+static constexpr const uint32_t kHeaderSize = sizeof(PacketHeader);
+static constexpr const uint32_t kPayloadSize = kPacketSize - kHeaderSize;
+
+ssize_t TrustyRpc(int handle, const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
+ uint8_t* iend) {
+ while (obegin != oend) {
+ PacketHeader header = {
+ .type = PacketType::SND,
+ .remaining = uint32_t(oend - obegin),
+ };
+ uint32_t body_size = std::min(kPayloadSize, header.remaining);
+ iovec iov[] = {
+ {
+ .iov_base = &header,
+ .iov_len = kHeaderSize,
+ },
+ {
+ .iov_base = const_cast<uint8_t*>(obegin),
+ .iov_len = body_size,
+ },
+ };
+ int rc = writev(handle, iov, 2);
+ if (!rc) {
+ PLOG(ERROR) << "Error sending SND message. " << rc;
+ return rc;
+ }
+
+ obegin += body_size;
+
+ rc = read(handle, &header, kHeaderSize);
+ if (!rc) {
+ PLOG(ERROR) << "Error reading ACK. " << rc;
+ return rc;
+ }
+
+ if (header.type != PacketType::ACK || header.remaining != oend - obegin) {
+ LOG(ERROR) << "malformed ACK";
+ return -1;
+ }
+ }
+
+ ssize_t remaining = 0;
+ auto begin = ibegin;
+ do {
+ PacketHeader header = {
+ .type = PacketType::RCV,
+ .remaining = 0,
+ };
+
+ iovec iov[] = {
+ {
+ .iov_base = &header,
+ .iov_len = kHeaderSize,
+ },
+ {
+ .iov_base = begin,
+ .iov_len = uint32_t(iend - begin),
+ },
+ };
+
+ ssize_t rc = writev(handle, iov, 1);
+ if (!rc) {
+ PLOG(ERROR) << "Error sending RCV message. " << rc;
+ return rc;
+ }
+
+ rc = readv(handle, iov, 2);
+ if (rc < 0) {
+ PLOG(ERROR) << "Error reading response. " << rc;
+ return rc;
+ }
+
+ uint32_t body_size = std::min(kPayloadSize, header.remaining);
+ if (body_size != rc - kHeaderSize) {
+ LOG(ERROR) << "Unexpected amount of data: " << rc;
+ return -1;
+ }
+
+ remaining = header.remaining - body_size;
+ begin += body_size;
+ } while (remaining);
+
+ return begin - ibegin;
+}
+
+TrustyApp::TrustyApp(const std::string& path, const std::string& appname)
+ : handle_(kInvalidHandle) {
+ handle_ = tipc_connect(path.c_str(), appname.c_str());
+ if (handle_ == kInvalidHandle) {
+ LOG(ERROR) << AT << "failed to connect to Trusty TA \"" << appname << "\" using dev:"
+ << "\"" << path << "\"";
+ }
+ LOG(INFO) << AT << "succeeded to connect to Trusty TA \"" << appname << "\"";
+}
+TrustyApp::~TrustyApp() {
+ if (handle_ != kInvalidHandle) {
+ tipc_close(handle_);
+ }
+ LOG(INFO) << "Done shutting down TrustyApp";
+}
+
+} // namespace trusty
+} // namespace android