1 /*
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 #include "TrustyApp.h"
18
19 #include <android-base/logging.h>
20 #include <sys/uio.h>
21 #include <trusty/tipc.h>
22
23 namespace android {
24 namespace trusty {
25
26 // 0x1000 is the message buffer size but we need to leave some space for a protocol header.
27 // This assures that packets can always be read/written in one read/write operation.
28 static constexpr const uint32_t kPacketSize = 0x1000 - 32;
29
30 enum class PacketType : uint32_t {
31 SND,
32 RCV,
33 ACK,
34 };
35
36 struct PacketHeader {
37 PacketType type;
38 uint32_t remaining;
39 };
40
toString(PacketType t)41 const char* toString(PacketType t) {
42 switch (t) {
43 case PacketType::SND:
44 return "SND";
45 case PacketType::RCV:
46 return "RCV";
47 case PacketType::ACK:
48 return "ACK";
49 default:
50 return "UNKNOWN";
51 }
52 }
53
54 static constexpr const uint32_t kHeaderSize = sizeof(PacketHeader);
55 static constexpr const uint32_t kPayloadSize = kPacketSize - kHeaderSize;
56
TrustyRpc(int handle,const uint8_t * obegin,const uint8_t * oend,uint8_t * ibegin,uint8_t * iend)57 ssize_t TrustyRpc(int handle, const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
58 uint8_t* iend) {
59 while (obegin != oend) {
60 PacketHeader header = {
61 .type = PacketType::SND,
62 .remaining = uint32_t(oend - obegin),
63 };
64 uint32_t body_size = std::min(kPayloadSize, header.remaining);
65 iovec iov[] = {
66 {
67 .iov_base = &header,
68 .iov_len = kHeaderSize,
69 },
70 {
71 .iov_base = const_cast<uint8_t*>(obegin),
72 .iov_len = body_size,
73 },
74 };
75 int rc = writev(handle, iov, 2);
76 if (!rc) {
77 PLOG(ERROR) << "Error sending SND message. " << rc;
78 return rc;
79 }
80
81 obegin += body_size;
82
83 rc = read(handle, &header, kHeaderSize);
84 if (!rc) {
85 PLOG(ERROR) << "Error reading ACK. " << rc;
86 return rc;
87 }
88
89 if (header.type != PacketType::ACK || header.remaining != oend - obegin) {
90 LOG(ERROR) << "malformed ACK";
91 return -1;
92 }
93 }
94
95 ssize_t remaining = 0;
96 auto begin = ibegin;
97 do {
98 PacketHeader header = {
99 .type = PacketType::RCV,
100 .remaining = 0,
101 };
102
103 iovec iov[] = {
104 {
105 .iov_base = &header,
106 .iov_len = kHeaderSize,
107 },
108 {
109 .iov_base = begin,
110 .iov_len = uint32_t(iend - begin),
111 },
112 };
113
114 ssize_t rc = writev(handle, iov, 1);
115 if (!rc) {
116 PLOG(ERROR) << "Error sending RCV message. " << rc;
117 return rc;
118 }
119
120 rc = readv(handle, iov, 2);
121 if (rc < 0) {
122 PLOG(ERROR) << "Error reading response. " << rc;
123 return rc;
124 }
125
126 uint32_t body_size = std::min(kPayloadSize, header.remaining);
127 if (body_size != rc - kHeaderSize) {
128 LOG(ERROR) << "Unexpected amount of data: " << rc;
129 return -1;
130 }
131
132 remaining = header.remaining - body_size;
133 begin += body_size;
134 } while (remaining);
135
136 return begin - ibegin;
137 }
138
TrustyApp(const std::string & path,const std::string & appname)139 TrustyApp::TrustyApp(const std::string& path, const std::string& appname)
140 : handle_(kInvalidHandle) {
141 handle_ = tipc_connect(path.c_str(), appname.c_str());
142 if (handle_ == kInvalidHandle) {
143 LOG(ERROR) << AT << "failed to connect to Trusty TA \"" << appname << "\" using dev:"
144 << "\"" << path << "\"";
145 }
146 LOG(INFO) << AT << "succeeded to connect to Trusty TA \"" << appname << "\"";
147 }
~TrustyApp()148 TrustyApp::~TrustyApp() {
149 if (handle_ != kInvalidHandle) {
150 tipc_close(handle_);
151 }
152 LOG(INFO) << "Done shutting down TrustyApp";
153 }
154
155 } // namespace trusty
156 } // namespace android
157