• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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