• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021, 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 <BufferAllocator/BufferAllocator.h>
20 #include <android-base/logging.h>
21 #include <sys/mman.h>
22 #include <sys/uio.h>
23 #include <trusty/tipc.h>
24 
25 #define countof(arr) (sizeof(arr) / sizeof(arr[0]))
26 
27 namespace android {
28 namespace trusty {
29 namespace confirmationui {
30 
31 using ::android::base::unique_fd;
32 
RoundPageUp(uintptr_t val)33 static inline uintptr_t RoundPageUp(uintptr_t val) {
34     return (val + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
35 }
36 
TrustyRpc(const uint8_t * obegin,const uint8_t * oend,uint8_t * ibegin,uint8_t * iend)37 ssize_t TrustyApp::TrustyRpc(const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
38                              uint8_t* iend) {
39     uint32_t olen = oend - obegin;
40 
41     if (olen > shm_len_) {
42         LOG(ERROR) << AT << "request message too long to fit in shared memory";
43         return -1;
44     }
45 
46     memcpy(shm_base_, obegin, olen);
47 
48     confirmationui_hdr hdr = {
49         .cmd = CONFIRMATIONUI_CMD_MSG,
50     };
51     confirmationui_msg_args args = {
52         .msg_len = olen,
53     };
54     iovec iov[] = {
55         {
56             .iov_base = &hdr,
57             .iov_len = sizeof(hdr),
58         },
59         {
60             .iov_base = &args,
61             .iov_len = sizeof(args),
62         },
63     };
64 
65     int rc = tipc_send(handle_, iov, countof(iov), NULL, 0);
66     if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
67         LOG(ERROR) << AT << "failed to send MSG request";
68         return -1;
69     }
70 
71     rc = readv(handle_, iov, countof(iov));
72     if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
73         LOG(ERROR) << AT << "failed to receive MSG response";
74         return -1;
75     }
76 
77     if (hdr.cmd != (CONFIRMATIONUI_CMD_MSG | CONFIRMATIONUI_RESP_BIT)) {
78         LOG(ERROR) << AT << "unknown response command: " << hdr.cmd;
79         return -1;
80     }
81 
82     uint32_t ilen = iend - ibegin;
83     if (args.msg_len > ilen) {
84         LOG(ERROR) << AT << "response message too long to fit in return buffer";
85         return -1;
86     }
87 
88     memcpy(ibegin, shm_base_, args.msg_len);
89 
90     return args.msg_len;
91 }
92 
TrustyApp(const std::string & path,const std::string & appname)93 TrustyApp::TrustyApp(const std::string& path, const std::string& appname)
94     : handle_(kInvalidHandle) {
95     unique_fd tipc_handle(tipc_connect(path.c_str(), appname.c_str()));
96     if (tipc_handle < 0) {
97         LOG(ERROR) << AT << "failed to connect to Trusty TA \"" << appname << "\" using dev:"
98                    << "\"" << path << "\"";
99         return;
100     }
101 
102     uint32_t shm_len = RoundPageUp(CONFIRMATIONUI_MAX_MSG_SIZE);
103     BufferAllocator allocator;
104     unique_fd dma_buf(allocator.Alloc("system", shm_len));
105     if (dma_buf < 0) {
106         LOG(ERROR) << AT << "failed to allocate shared memory buffer";
107         return;
108     }
109 
110     confirmationui_hdr hdr = {
111         .cmd = CONFIRMATIONUI_CMD_INIT,
112     };
113     confirmationui_init_req args = {
114         .shm_len = shm_len,
115     };
116     iovec iov[] = {
117         {
118             .iov_base = &hdr,
119             .iov_len = sizeof(hdr),
120         },
121         {
122             .iov_base = &args,
123             .iov_len = sizeof(args),
124         },
125     };
126     trusty_shm shm = {
127         .fd = dma_buf,
128         .transfer = TRUSTY_SHARE,
129     };
130 
131     int rc = tipc_send(tipc_handle, iov, 2, &shm, 1);
132     if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
133         LOG(ERROR) << AT << "failed to send INIT request";
134         return;
135     }
136 
137     rc = read(tipc_handle, &hdr, sizeof(hdr));
138     if (rc != static_cast<int>(sizeof(hdr))) {
139         LOG(ERROR) << AT << "failed to receive INIT response";
140         return;
141     }
142 
143     if (hdr.cmd != (CONFIRMATIONUI_CMD_INIT | CONFIRMATIONUI_RESP_BIT)) {
144         LOG(ERROR) << AT << "unknown response command: " << hdr.cmd;
145         return;
146     }
147 
148     void* shm_base = mmap(0, shm_len, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
149     if (shm_base == MAP_FAILED) {
150         LOG(ERROR) << AT << "failed to mmap() shared memory buffer";
151         return;
152     }
153 
154     handle_ = std::move(tipc_handle);
155     shm_base_ = shm_base;
156     shm_len_ = shm_len;
157 
158     LOG(INFO) << AT << "succeeded to connect to Trusty TA \"" << appname << "\"";
159 }
160 
~TrustyApp()161 TrustyApp::~TrustyApp() {
162     LOG(INFO) << "Done shutting down TrustyApp";
163 }
164 
165 }  // namespace confirmationui
166 }  // namespace trusty
167 }  // namespace android
168