blob: fb57828f95f40a5424d609a88801c3ce42c4c925 [file] [log] [blame]
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -08001/*
2 * Copyright 2020, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
Tri Voabd86f82021-02-19 22:09:22 -080019#include <TrustyIpc.h>
Tri Vo19b62a52021-02-16 11:51:26 -080020
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -080021#include <android-base/logging.h>
Tri Vo19b62a52021-02-16 11:51:26 -080022#include <android-base/unique_fd.h>
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -080023#include <errno.h>
24#include <poll.h>
25#include <stdio.h>
26#include <sys/eventfd.h>
27#include <sys/stat.h>
28#include <teeui/msg_formatting.h>
29#include <trusty/tipc.h>
30#include <unistd.h>
31
32#include <fstream>
33#include <functional>
34#include <future>
35#include <iostream>
36#include <sstream>
37#include <thread>
38#include <vector>
39
40#define AT __FILE__ ":" << __LINE__ << ": "
41
42namespace android {
43namespace trusty {
Tri Voabd86f82021-02-19 22:09:22 -080044namespace confirmationui {
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -080045
46using ::teeui::Message;
47using ::teeui::msg2tuple_t;
48using ::teeui::ReadStream;
49using ::teeui::WriteStream;
50
51#ifndef TEEUI_USE_STD_VECTOR
52/*
53 * TEEUI_USE_STD_VECTOR makes certain wire types like teeui::MsgString and
54 * teeui::MsgVector be aliases for std::vector. This is required for thread safe
55 * message serialization. Always compile this with -DTEEUI_USE_STD_VECTOR set in
56 * CFLAGS of the HAL service.
57 */
58#error "Must be compiled with -DTEEUI_USE_STD_VECTOR."
59#endif
60
61enum class TrustyAppError : int32_t {
62 OK,
63 ERROR = -1,
64 MSG_TOO_LONG = -2,
65};
66
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -080067class TrustyApp {
68 private:
Tri Vo19b62a52021-02-16 11:51:26 -080069 android::base::unique_fd handle_;
70 void* shm_base_;
71 size_t shm_len_;
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -080072 static constexpr const int kInvalidHandle = -1;
73 /*
74 * This mutex serializes communication with the trusted app, not handle_.
75 * Calling issueCmd during construction or deletion is undefined behavior.
76 */
77 std::mutex mutex_;
78
79 public:
80 TrustyApp(const std::string& path, const std::string& appname);
81 ~TrustyApp();
82
Tri Vo19b62a52021-02-16 11:51:26 -080083 ssize_t TrustyRpc(const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin, uint8_t* iend);
84
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -080085 template <typename Request, typename Response, typename... T>
86 std::tuple<TrustyAppError, msg2tuple_t<Response>> issueCmd(const T&... args) {
87 std::lock_guard<std::mutex> lock(mutex_);
88
89 if (handle_ == kInvalidHandle) {
90 LOG(ERROR) << "TrustyApp not connected";
91 return {TrustyAppError::ERROR, {}};
92 }
93
Tri Vo19b62a52021-02-16 11:51:26 -080094 uint8_t buffer[CONFIRMATIONUI_MAX_MSG_SIZE];
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -080095 WriteStream out(buffer);
96
97 out = write(Request(), out, args...);
98 if (!out) {
99 LOG(ERROR) << AT << "send command failed: message formatting";
100 return {TrustyAppError::MSG_TOO_LONG, {}};
101 }
102
Tri Vo19b62a52021-02-16 11:51:26 -0800103 auto rc = TrustyRpc(&buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
104 &buffer[CONFIRMATIONUI_MAX_MSG_SIZE]);
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -0800105 if (rc < 0) return {TrustyAppError::ERROR, {}};
106
107 ReadStream in(&buffer[0], rc);
108 auto result = read(Response(), in);
109 if (!std::get<0>(result)) {
110 LOG(ERROR) << "send command failed: message parsing";
111 return {TrustyAppError::ERROR, {}};
112 }
113
114 return {std::get<0>(result) ? TrustyAppError::OK : TrustyAppError::ERROR,
115 tuple_tail(std::move(result))};
116 }
117
118 template <typename Request, typename... T> TrustyAppError issueCmd(const T&... args) {
119 std::lock_guard<std::mutex> lock(mutex_);
120
121 if (handle_ == kInvalidHandle) {
122 LOG(ERROR) << "TrustyApp not connected";
123 return TrustyAppError::ERROR;
124 }
125
Tri Vo19b62a52021-02-16 11:51:26 -0800126 uint8_t buffer[CONFIRMATIONUI_MAX_MSG_SIZE];
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -0800127 WriteStream out(buffer);
128
129 out = write(Request(), out, args...);
130 if (!out) {
131 LOG(ERROR) << AT << "send command failed: message formatting";
132 return TrustyAppError::MSG_TOO_LONG;
133 }
134
Tri Vo19b62a52021-02-16 11:51:26 -0800135 auto rc = TrustyRpc(&buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
136 &buffer[CONFIRMATIONUI_MAX_MSG_SIZE]);
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -0800137 if (rc < 0) {
138 LOG(ERROR) << "send command failed: " << strerror(errno) << " (" << errno << ")";
139 return TrustyAppError::ERROR;
140 }
141
142 if (rc > 0) {
143 LOG(ERROR) << "Unexpected non zero length response";
144 return TrustyAppError::ERROR;
145 }
146 return TrustyAppError::OK;
147 }
148
149 operator bool() const { return handle_ != kInvalidHandle; }
150};
151
Tri Voabd86f82021-02-19 22:09:22 -0800152} // namespace confirmationui
Janis Danisevskis8fe0cfb2020-01-13 14:24:32 -0800153} // namespace trusty
154} // namespace android