1 <html devsite> 2 <head> 3 <title>Trusty API Reference</title> 4 <meta name="project_path" value="/_project.yaml" /> 5 <meta name="book_path" value="/_book.yaml" /> 6 </head> 7 <body> 8 <!-- 9 Copyright 2017 The Android Open Source Project 10 11 Licensed under the Apache License, Version 2.0 (the "License"); 12 you may not use this file except in compliance with the License. 13 You may obtain a copy of the License at 14 15 http://www.apache.org/licenses/LICENSE-2.0 16 17 Unless required by applicable law or agreed to in writing, software 18 distributed under the License is distributed on an "AS IS" BASIS, 19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 See the License for the specific language governing permissions and 21 limitations under the License. 22 --> 23 24 25 26 <p>The <a href="index.html">Trusty</a> API generally describes the 27 Trusty inter-process communication (IPC) 28 system, including communications with the non-secure world. This page defines the 29 relevant terms and provides a reference for the API 30 calls.</p> 31 32 <h2 id=ports_and_channels>Ports and channels</h2> 33 34 <p>Ports are used by Trusty applications to expose service end-points in the form 35 of a named path to which clients connect. This gives a simple, string-based 36 service ID for clients to use. The naming convention is reverse-DNS-style 37 naming, e.g. <code>com.google.servicename</code>.</p> 38 39 <p>When a client connects to a port, the client receives a channel for interacting 40 with a service. The service must accept an incoming connection, and when it 41 does, it too receives a channel. In essence, ports are used to look up services 42 and then communication occurs over a pair of connected channels (i.e., 43 connection instances on a port). When a client connects to a port, a symmetric, 44 bi-directional connection is established. Using this full-duplex path, clients 45 and servers can exchange arbitrary messages until either side decides to tear 46 down the connection.</p> 47 48 <p>Only secure-side trusted applications or Trusty kernel modules can create 49 ports. Applications running on the non-secure side (in the normal world) can 50 only connect to services published by the secure side.</p> 51 52 <p>Depending on requirements, a trusted application can be both a client and a 53 server at the same time. A trusted application that publishes a service (as a 54 server) might need to connect to other services (as a client).</p> 55 56 <h2 id=handle_api>Handle API</h2> 57 58 <p>Handles are unsigned integers representing resources such as ports and 59 channels, similar to file descriptors in UNIX. After handles are created, they 60 are placed into an application-specific handle table and can be referenced 61 later.</p> 62 63 <p>A caller can associate private data with a handle by using 64 the <code>set_cookie()</code> method.</p> 65 66 <h3 id=methods_handle_api>Methods in the Handle API</h3> 67 68 <p>Handles are only valid in the context of an application. An application should 69 not pass the value of a handle to other applications unless explicitly 70 specified. A handle value only should be interpreted by comparing it with 71 the <code>INVALID_IPC_HANDLE #define,</code> which an application can use as an 72 indication that a handle is invalid or unset.</p> 73 74 <h4 id=set_cookie>set_cookie()</h4> 75 76 <p>Associates the caller-provided private data with a specified handle.</p> 77 78 <pre class="prettyprint"> 79 long set_cookie(uint32_t handle, void *cookie) 80 </pre> 81 82 <p>[in] <code>handle</code>: Any handle returned by one of the API calls</p> 83 84 <p>[in] <code>cookie</code>: Pointer to arbitrary user-space data in the Trusty application</p> 85 86 <p>[retval]: <code>NO_ERROR</code> on success, <code>< 0</code> error code otherwise</p> 87 88 <p>This call is useful for handling events when they occur at a later time after 89 the handle has been created. The event-handling mechanism supplies the handle 90 and its cookie back to the event handler.</p> 91 92 <p>Handles can be waited upon for events by using the <code>wait()</code> 93 or <code>wait_any()</code> calls.</p> 94 95 <h4 id=wait>wait()</h4> 96 97 <p>Waits for an event to occur on a given handle for specified period of time.</p> 98 99 <pre class="prettyprint"> 100 long wait(uint32_t handle_id, uevent_t *event, unsigned long timeout_msecs) 101 </pre> 102 103 <p>[in] <code>handle_id</code>: Any handle returned by one of the API calls</p> 104 105 <p>[out] <code>event</code>: A pointer to the structure representing 106 an event that occurred on this handle</p> 107 108 <p>[in] <code>timeout_msecs</code>: A timeout value in milliseconds; a 109 value of -1 is an infinite timeout</p> 110 111 <p>[retval]: <code>NO_ERROR</code> if a valid event occurred within a 112 specified timeout interval; <code>ERR_TIMED_OUT</code> if a specified timeout elapsed but no 113 event has occurred; <code>< 0</code> for other errors</p> 114 115 <h4 id=wait_any>wait_any()</h4> 116 117 <p>Waits for any event to occur on any handle in the application handle table for 118 the specified period of time.</p> 119 120 <pre class="prettyprint"> 121 long wait_any(uevent_t *event, unsigned long timeout_msecs); 122 </pre> 123 124 <p>[out] <code>event</code>: A pointer to the structure representing an 125 event that occurred on this handle</p> 126 127 <p>[in] <code>timeout_msecs</code>: A timeout value in milliseconds. 128 A value of -1 is an infinite timeout</p> 129 130 <p>[retval]: <code>NO_ERROR</code> if a valid event occurred within a 131 specified timeout interval; <code>ERR_TIMED_OUT</code> if a specified timeout elapsed but no 132 event has occurred; <code>< 0</code> for other errors</p> 133 134 <p>Upon success (<code>retval == NO_ERROR</code>), the <code>wait()</code> 135 and <code>wait_any()</code> calls 136 fill a specified <code>uevent_t</code> structure with information about 137 the event that occurred.</p> 138 139 <pre class="prettyprint"> 140 typedef struct uevent { 141 uint32_t handle; /* handle this event is related to */ 142 uint32_t event; /* combination of IPC_HANDLE_POLL_XXX flags */ 143 void *cookie; /* cookie associated with this handle */ 144 } uevent_t; 145 </pre> 146 147 <p>The <code>event</code> field contains a combination of the following values:</p> 148 149 <pre class="prettyprint"> 150 enum { 151 IPC_HANDLE_POLL_NONE = 0x0, 152 IPC_HANDLE_POLL_READY = 0x1, 153 IPC_HANDLE_POLL_ERROR = 0x2, 154 IPC_HANDLE_POLL_HUP = 0x4, 155 IPC_HANDLE_POLL_MSG = 0x8, 156 IPC_HANDLE_POLL_SEND_UNBLOCKED = 0x10, 157 more values[TBD] 158 }; 159 </pre> 160 161 <p><code>IPC_HANDLE_POLL_NONE</code> - no events are actually pending, 162 caller should restart the wait</p> 163 164 <p><code>IPC_HANDLE_POLL_ERROR</code> - an unspecified internal error has occurred</p> 165 166 <p><code>IPC_HANDLE_POLL_READY</code> - depends on the handle type, as follows:</p> 167 168 <ul> 169 <li>For ports, this value indicates that there is a pending connection 170 <li>For channels, this value indicates that an asynchronous connection 171 (see <code>connect()</code>) was established 172 </ul> 173 174 <p>The following events are only relevant for channels:</p> 175 176 <ul> 177 <li><code>IPC_HANDLE_POLL_HUP</code> - indicates that a channel has been closed by a peer 178 <li><code>IPC_HANDLE_POLL_MSG</code> - indicates that there is a pending message for this channel 179 <li><code>IPC_HANDLE_POLL_SEND_UNBLOCKED</code> - indicates that a previously 180 send-blocked caller may attempt to send a 181 message again (see the description of <code>send_msg()</code> for details) 182 </ul> 183 184 <p>An event handler should be prepared to handle a combination of specified 185 events, as multiple bits might be set at the same time. For example, for a 186 channel, it is possible to have pending messages, and a connection closed by a 187 peer at the same time.</p> 188 189 <p>Most events are sticky. They persist as long as the underlying condition 190 persists (for example all pending messages are received and pending connection 191 requests are handled). The exception is the case of 192 the <code>IPC_HANDLE_POLL_SEND_UNBLOCKED</code> event, which 193 is cleared upon a read and the application has only one chance to 194 handle it.</p> 195 196 <p>Handles can be destroyed by calling the <code>close()</code> method.</p> 197 198 <h4 id=close>close()</h4> 199 200 <p>Destroys the resource associated with the specified handle and removes it from 201 the handle table.</p> 202 203 <pre class="prettyprint"> 204 long close(uint32_t handle_id); 205 </pre> 206 207 <p>[in] <code>handle_id</code>: Handle to destroy</p> 208 209 <p>[retval]: 0 if success; a negative error otherwise</p> 210 211 <h2 id=server_api>Server API</h2> 212 213 <p>A server begins by creating one or more <strong>named ports</strong> representing 214 its service end-points. Each port is represented by a handle.</p> 215 216 <h3 id=methods_server_api>Methods in the Server API</h3> 217 218 <h4 id=port_create>port_create()</h4> 219 220 <p>Creates a named service port.</p> 221 222 <pre class="prettyprint"> 223 long port_create (const char *path, uint num_recv_bufs, size_t recv_buf_size, 224 uint32_t flags) 225 </pre> 226 227 <p>[in] <code>path</code>: The string name of the port (as described above). This 228 name should be unique across the system; attempts to create a duplicate will fail.</p> 229 230 <p>[in] <code>num_recv_bufs</code>: The maximum number of buffers that a channel on 231 this port can pre-allocate to facilitate the exchange of data with the client. Buffers are counted 232 separately for data going in both directions, so specifying 1 here would mean 1 233 send and 1 receive buffer are preallocated. In general, the number of buffers 234 required depends on the higher-level protocol agreement between the client and 235 server. The number can be as little as 1 in case of a very synchronous protocol 236 (send message, receive reply before sending another). But the number can be 237 more if the client expects to send more than one message before a reply can 238 appear (e.g, one message as a prologue and another as the actual command). The 239 allocated buffer sets are per channel, so two separate connections (channels) 240 would have separate buffer sets.</p> 241 242 <p>[in] <code>recv_buf_size</code>: Maximum size of each individual buffer in the 243 above buffer set. This value is 244 protocol-dependent and effectively limits maximum message size you can exchange 245 with peer</p> 246 247 <p>[in] <code>flags</code>: A combination of flags that specifies additional port behavior</p> 248 249 <p>This value should be a combination of the following values:</p> 250 251 <p><code>IPC_PORT_ALLOW_TA_CONNECT</code> - allows a connection from other secure apps</p> 252 253 <p><code>IPC_PORT_ALLOW_NS_CONNECT</code> - allows a connection from the non-secure world</p> 254 255 <p>[retval]: Handle to the port created if non-negative or a specific error if 256 negative</p> 257 258 <p>The server then polls the list of port handles for incoming connections 259 using <code>wait()</code> or <code>wait_any()</code> calls. Upon receiving a connection 260 request indicated by the <code>IPC_HANDLE_POLL_READY</code> bit set in 261 the <code>event</code> field of the <code>uevent_t</code> structure, the 262 server should call <code>accept()</code> to finish establishing a connection and create a 263 channel (represented by 264 another handle) that can then be polled for incoming messages.</p> 265 266 <h4 id=accept>accept()</h4> 267 268 <p>Accepts an incoming connection and gets a handle to a channel.</p> 269 270 <pre class="prettyprint"> 271 long accept(uint32_t handle_id, uuid_t *peer_uuid); 272 </pre> 273 274 <p>[in] <code>handle_id</code>: Handle representing the port to which a client has connected</p> 275 276 <p>[out] <code>peer_uuid</code>: Pointer to a <code>uuud_t</code> structure to be 277 filled with the UUID of the connecting client application. It 278 will be set to all zeros if the connection originated from the non-secure world</p> 279 280 <p>[retval]: Handle to a channel (if non-negative) on which the server can 281 exchange messages with the client (or an error code otherwise)</p> 282 283 <h2 id=client_api>Client API</h2> 284 285 <p>This section contains the methods in the Client API.</p> 286 287 <h3 id=methods_client_api>Methods in the Client API</h3> 288 289 <h4 id=connect>connect()</h4> 290 291 <p>Initiates a connection to a port specified by name.</p> 292 293 <pre class="prettyprint"> 294 long connect(const char *path, uint flags); 295 </pre> 296 297 <p>[in] <code>path</code>: Name of a port published by a Trusty application</p> 298 299 <p>[in] <code>flags</code>: Specifies additional, optional behavior</p> 300 301 <p>[retval]: Handle to a channel over which messages can be exchanged with the 302 server; error if negative</p> 303 304 <p>If no <code>flags</code> are specified (the <code>flags</code> parameter 305 is set to 0), calling <code>connect()</code> initiates a synchronous connection 306 to a specified port that immediately 307 returns an error if the port does not exist, and creates a block until the 308 server otherwise accepts a connection.</p> 309 310 <p>This behavior can be altered by specifying a combination of two values, 311 described below:</p> 312 313 <pre class="prettyprint"> 314 enum { 315 IPC_CONNECT_WAIT_FOR_PORT = 0x1, 316 IPC_CONNECT_ASYNC = 0x2, 317 }; 318 </pre> 319 320 <p><code>IPC_CONNECT_WAIT_FOR_PORT</code> - forces a <code>connect()</code> 321 call to wait if the specified port does not immediately exist at execution, 322 instead of failing immediately.</p> 323 324 <p><code>IPC_CONNECT_ASYNC</code> - if set, initiates an asynchronous connection. An 325 application has to poll for 326 the returned handle (by calling <code>wait()</code> or <code>wait_any()</code>) for 327 a connection completion event indicated by the <code>IPC_HANDLE_POLL_READY</code> 328 bit set in the event field of the <code>uevent_t</code> structure before starting 329 normal operation.</p> 330 331 <h2 id=messaging_api>Messaging API</h2> 332 333 <p>The Messaging API calls enable the sending and reading of messages over a 334 previously established connection (channel). The Messaging API calls are the 335 same for servers and clients.</p> 336 337 <p>A client receives a handle to a channel by issuing a <code>connect()</code> 338 call, and a server gets a channel handle from an <code>accept()</code> call, 339 described above.</p> 340 341 <h4 id=structure_of_a_trusty_message>Structure of a Trusty message</h4> 342 343 <p>As shown in the following, messages exchanged by the Trusty API have a minimal 344 structure, leaving it to the server and client to agree on the semantics of the 345 actual contents:</p> 346 347 <pre class="prettyprint"> 348 /* 349 * IPC message 350 */ 351 typedef struct iovec { 352 void *base; 353 size_t len; 354 } iovec_t; 355 356 typedef struct ipc_msg { 357 uint num_iov; /* number of iovs in this message */ 358 iovec_t *iov; /* pointer to iov array */ 359 360 uint num_handles; /* reserved, currently not supported */ 361 handle_t *handles; /* reserved, currently not supported */ 362 } ipc_msg_t; 363 </pre> 364 365 <p>A message can be composed of one or more non-contiguous buffers represented by 366 an array of <code>iovec_t</code> structures. Trusty performs scatter-gather 367 reads and writes to these blocks 368 using the <code>iov</code> array. The content of buffers that can be described 369 by the <code>iov</code> array is completely arbitrary.</p> 370 371 <h3 id=methods_messaging_api>Methods in the Messaging API</h3> 372 373 <h4 id=send_msg>send_msg()</h4> 374 375 <p>Sends a message over a specified channel.</p> 376 377 <pre class="prettyprint"> 378 long send_msg(uint32_t handle, ipc_msg_t *msg); 379 </pre> 380 381 <p>[in] <code>handle</code>: Handle to the channel over which to send the message</p> 382 383 <p>[in] <code>msg</code>: Pointer to the <code>ipc_msg_t structure</code> describing the message</p> 384 385 <p>[retval]: Total number of bytes sent on success; a negative error otherwise</p> 386 387 <p>If the client (or server) is trying to send a message over the channel and 388 there is no space in the destination peer message queue, the channel might 389 enter a send-blocked state (this should never happen for a simple synchronous 390 request/reply protocol but might happen in more complicated cases) that is 391 indicated by returning an <code>ERR_NOT_ENOUGH_BUFFER</code> error code. 392 In such a case the caller must wait until the peer frees some 393 space in its receive queue by retrieving the handling and retiring messages, 394 indicated by the <code>IPC_HANDLE_POLL_SEND_UNBLOCKED</code> bit set in 395 the <code>event</code> field of the <code>uevent_t</code> structure 396 returned by the <code>wait()</code> or <code>wait_any()</code> call.</p> 397 398 <h4 id=get_msg>get_msg()</h4> 399 400 <p>Gets meta-information about the next message in an incoming message queue</p> 401 402 <p>of a specified channel.</p> 403 404 <pre class="prettyprint"> 405 long get_msg(uint32_t handle, ipc_msg_info_t *msg_info); 406 </pre> 407 408 <p>[in] <code>handle</code>: Handle of the channel on which a new message must be retrieved</p> 409 410 <p>[out] <code>msg_info</code>: Message information structure described as follows:</p> 411 412 <pre class="prettyprint"> 413 typedef struct ipc_msg_info { 414 size_t len; /* total message length */ 415 uint32_t id; /* message id */ 416 } ipc_msg_info_t; 417 </pre> 418 419 <p>Each message is assigned a unique ID across the set of outstanding messages, 420 and the total length of each message is filled in. If configured and allowed by the 421 protocol, there can be multiple outstanding (opened) messages at once for a 422 particular channel.</p> 423 424 <p>[retval]: <code>NO_ERROR</code> on success; a negative error otherwise</p> 425 426 <h4 id=read_msg>read_msg()</h4> 427 428 <p>Reads the content of the message with the specified ID starting from the 429 specified offset.</p> 430 431 <pre class="prettyprint"> 432 long read_msg(uint32_t handle, uint32_t msg_id, uint32_t offset, ipc_msg_t 433 *msg); 434 </pre> 435 436 <p>[in] <code>handle</code>: Handle of the channel from which to read the message</p> 437 438 <p>[in] <code>msg_id</code>: ID of the message to read</p> 439 440 <p>[in] <code>offset</code>: Offset into the message from which to start reading</p> 441 442 <p>[in] <code>msg</code>: Pointer to the <code>ipc_msg_t</code> structure describing 443 a set of buffers into which to store incoming message 444 data</p> 445 446 <p>[retval]: Total number of bytes stored in the <code>dst</code> buffers on 447 success; a negative error otherwise</p> 448 449 <p>The <code>read_msg</code> method can be called multiple times starting at 450 a different (not necessarily 451 sequential) offset as needed.</p> 452 453 <h4 id=put_msg>put_msg()</h4> 454 455 <p>Retires a message with a specified ID.</p> 456 457 <pre class="prettyprint"> 458 long put_msg(uint32_t handle, uint32_t msg_id); 459 </pre> 460 461 <p>[in] <code>handle</code>: Handle of the channel on which the message has arrived</p> 462 463 <p>[in] <code>msg_id</code>: ID of message being retired</p> 464 465 <p>[retval]: <code>NO_ERROR</code> on success; a negative error otherwise</p> 466 467 <p>Message content cannot be accessed after a message has been retired and the 468 buffer it occupied has been freed.</p> 469 470 <h2 id=file_descriptor_api>File Descriptor API</h2> 471 472 <p>The File Descriptor API includes <code>read()</code>, <code>write()</code>, 473 and <code>ioctl()</code> calls. All of these calls can operate on a predefined (static) set of file 474 descriptors traditionally represented by small numbers. In the current 475 implementation, the file descriptor space is separate from the IPC handle 476 space. The File Descriptor API in Trusty is 477 similar to a traditional file descriptor-based API.</p> 478 479 <p>By default, there are 3 predefined (standard and well-known) file descriptors:</p> 480 481 <ul> 482 <li>0 - standard input. The default implementation of standard input <code>fd</code> 483 is a no-op (as trusted applications are not expected to have an interactive 484 console) so reading, writing or invoking <code>ioctl()</code> on <code>fd</code> 0 485 should return an <code>ERR_NOT_SUPPORTED</code> error. 486 <li>1 - standard output. Data written to standard output can be routed (depending 487 on the LK debug level) to UART and/or a memory log available on the non-secure 488 side, depending on the platform and configuration. Non-critical debug logs and 489 messages should go in standard output. The <code>read()</code> and <code>ioctl()</code> 490 methods are no-ops and should return an <code>ERR_NOT_SUPPORTED</code> error. 491 <li>2 - standard error. Data written to standard error should be routed to the UART 492 or memory log available on the non-secure side, depending on the platform and 493 configuration. It is recommended to write only critical messages to standard 494 error, as this stream is very likely to be unthrottled. The <code>read()</code> and 495 <code>ioctl()</code> methods are no-ops and should return an <code>ERR_NOT_SUPPORTED</code> error. 496 </ul> 497 498 <p>Even though this set of file descriptors can be extended to implement more 499 <code>fds</code> (to implement platform-specific extensions), extending file descriptors needs 500 to be exercised with caution. Extending file descriptors is prone to create 501 conflicts and is not generally recommended.</p> 502 503 <h3 id=methods_file_descriptor_api>Methods in the File Descriptor API</h3> 504 505 <h4 id=read>read()</h4> 506 507 <p>Attempts to read up to <code>count</code> bytes of data from a specified file descriptor.</p> 508 509 <pre class="prettyprint"> 510 long read(uint32_t fd, void *buf, uint32_t count); 511 </pre> 512 513 <p>[in] <code>fd</code>: File descriptor from which to read</p> 514 515 <p>[out] <code>buf</code>: Pointer to a buffer into which to store data</p> 516 517 <p>[in] <code>count</code>: Maximum number of bytes to read</p> 518 519 <p>[retval]: Returned number of bytes read; a negative error otherwise</p> 520 521 <h4 id=write>write()</h4> 522 523 <p>Writes up to <code>count</code> bytes of data to specified file descriptor.</p> 524 525 <pre class="prettyprint"> 526 long write(uint32_t fd, void *buf, uint32_t count); 527 </pre> 528 529 <p>[in] <code>fd</code>: File descriptor to which to write</p> 530 531 <p>[out] <code>buf</code>: Pointer to data to write</p> 532 533 <p>[in] <code>count</code>: Maximum number of bytes to write</p> 534 535 <p>[retval]: Returned number of bytes written; a negative error otherwise</p> 536 537 <h4 id=ioctl>ioctl()</h4> 538 539 <p>Invokes a specified <code>ioctl</code> command for a given file descriptor.</p> 540 541 <pre class="prettyprint"> 542 long ioctl(uint32_t fd, uint32_t cmd, void *args); 543 </pre> 544 545 <p>[in] <code>fd</code>: File descriptor on which to invoke <code>ioctl()</code></p> 546 547 <p>[in] <code>cmd</code>: The <code>ioctl</code> command</p> 548 549 <p>[in/out] <code>args</code>: Pointer to <code>ioctl()</code> arguments</p> 550 551 <h2 id=miscellaneous_api>Miscellaneous API</h2> 552 553 <h3 id=methods_misc_api>Methods in the Miscellaneous API</h3> 554 555 <h4 id=gettime>gettime()</h4> 556 557 <p>Returns the current system time (in nanoseconds).</p> 558 559 <pre class="prettyprint"> 560 long gettime(uint32_t clock_id, uint32_t flags, uint64_t *time); 561 </pre> 562 563 <p>[in] <code>clock_id</code>: Platform-dependent; pass zero for default</p> 564 565 <p>[in] <code>flags</code>: Reserved, should be zero</p> 566 567 <p>[in] <code>time</code>: Pointer to an <code>int64_t</code> value to which to store the current time</p> 568 569 <p>[retval]: <code>NO_ERROR</code> on success; a negative error otherwise</p> 570 571 <h4 id=nanosleep>nanosleep()</h4> 572 573 <p>Suspends execution of the calling application for a specified period of time 574 and resumes it after that period.</p> 575 576 <pre class="prettyprint"> 577 long nanosleep(uint32_t clock_id, uint32_t flags, uint64_t sleep_time) 578 </pre> 579 580 <p>[in] <code>clock_id</code>: Reserved, should be zero</p> 581 582 <p>[in] <code>flags</code>: Reserved, should be zero</p> 583 584 <p>[in] <code>sleep_time</code>: Sleep time in nanoseconds</p> 585 586 <p>[retval]: <code>NO_ERROR</code> on success; a negative error otherwise</p> 587 588 <h2 id=example_of_a_trusted_application_server>Example of a trusted application server</h2> 589 590 <p>The following sample application shows the usage of the above APIs. The sample 591 creates an "echo" service that handles multiple incoming connections and 592 reflects back to the caller all messages it receives from clients originated 593 from the secure or non-secure side.</p> 594 595 <pre class="prettyprint"> 596 #include <assert.h> 597 #include <err.h> 598 #include <stddef.h> 599 #include <stdio.h> 600 #include <stdlib.h> 601 #include <string.h> 602 #include <trusty_std.h> 603 604 #include <app/echo/uuids.h> 605 606 #define LOG_TAG "echo_srv" 607 608 #define TLOGE(fmt, ...) \ 609 fprintf(stderr, "%s: %d: " fmt, LOG_TAG, __LINE__, ## __VA_ARGS__) 610 611 #define MAX_ECHO_MSG_SIZE 64 612 613 static const char *srv_name = "com.android.echo.srv.echo"; 614 615 static uint8_t msg_buf[MAX_ECHO_MSG_SIZE]; 616 617 /* 618 * Message handler 619 */ 620 static int handle_msg(handle_t chan) 621 { 622 int rc; 623 iovec_t iov; 624 ipc_msg_t msg; 625 ipc_msg_info_t msg_inf; 626 627 iov.base = msg_buf; 628 iov.len = sizeof(msg_buf); 629 630 msg.num_iov = 1; 631 msg.iov = &iov; 632 msg.num_handles = 0; 633 msg.handles = NULL; 634 635 /* get message info */ 636 rc = get_msg(chan, &msg_inf); 637 if (rc == ERR_NO_MSG) 638 return NO_ERROR; /* no new messages */ 639 640 if (rc != NO_ERROR) { 641 TLOGE("failed (%d) to get_msg for chan (%d)\n", 642 rc, chan); 643 return rc; 644 } 645 646 /* read msg content */ 647 rc = read_msg(chan, msg_inf.id, 0, &msg); 648 if (rc < 0) { 649 TLOGE("failed (%d) to read_msg for chan (%d)\n", 650 rc, chan); 651 return rc; 652 } 653 654 /* update number of bytes received */ 655 iov.len = (size_t) rc; 656 657 /* send message back to the caller */ 658 rc = send_msg(chan, &msg); 659 if (rc < 0) { 660 TLOGE("failed (%d) to send_msg for chan (%d)\n", 661 rc, chan); 662 return rc; 663 } 664 665 /* retire message */ 666 rc = put_msg(chan, msg_inf.id); 667 if ( rc != NO_ERROR) { 668 TLOGE("failed (%d) to put_msg for chan (%d)\n", 669 rc, chan); 670 return rc; 671 } 672 673 return NO_ERROR; 674 } 675 676 /* 677 * Channel event handler 678 */ 679 static void handle_channel_event(const uevent_t *ev) 680 { 681 int rc; 682 683 if (ev->event & IPC_HANDLE_POLL_MSG) { 684 rc = handle_msg(ev->handle); 685 if (rc != NO_ERROR) { 686 /* report an error and close channel */ 687 TLOGE("failed (%d) to handle event on channel %d\n", 688 rc, ev->handle); 689 close(ev->handle); 690 } 691 return; 692 } 693 if (ev->event & IPC_HANDLE_POLL_HUP) { 694 /* closed by peer. */ 695 close(ev->handle); 696 return; 697 } 698 } 699 700 /* 701 * Port event handler 702 */ 703 static void handle_port_event(const uevent_t *ev) 704 { 705 uuid_t peer_uuid; 706 707 if ((ev->event & IPC_HANDLE_POLL_ERROR) || 708 (ev->event & IPC_HANDLE_POLL_HUP) || 709 (ev->event & IPC_HANDLE_POLL_MSG) || 710 (ev->event & IPC_HANDLE_POLL_SEND_UNBLOCKED)) { 711 /* should never happen with port handles */ 712 TLOGE("error event (0x%x) for port (%d)\n", 713 ev->event, ev->handle); 714 abort(); 715 } 716 if (ev->event & IPC_HANDLE_POLL_READY) { 717 /* incoming connection: accept it */ 718 int rc = accept(ev->handle, &peer_uuid); 719 if (rc < 0) { 720 TLOGE("failed (%d) to accept on port %d\n", 721 rc, ev->handle); 722 return; 723 } 724 } 725 } 726 727 /* 728 * Main application entry point 729 */ 730 int main(void) 731 { 732 int rc; 733 handle_t port; 734 735 /* Initialize service */ 736 rc = port_create(srv_name, 1, MAX_ECHO_MSG_SIZE, 737 IPC_PORT_ALLOW_NS_CONNECT | 738 IPC_PORT_ALLOW_TA_CONNECT ); 739 if (rc < 0) { 740 TLOGE("Failed (%d) to create port %s\n", 741 rc, srv_name); 742 abort(); 743 } 744 port = (handle_t)rc; 745 746 /* enter main event loop */ 747 while (true) { 748 uevent_t ev; 749 750 ev.handle = INVALID_IPC_HANDLE; 751 ev.event = 0; 752 ev.cookie = NULL; 753 754 /* wait forever */ 755 rc = wait_any(&ev, -1); 756 if (rc == NO_ERROR) { 757 /* got an event */ 758 if (ev.handle == port) { 759 handle_port_event(&ev); 760 } else { 761 handle_channel_event(&ev); 762 } 763 } else { 764 TLOGE("wait_any returned (%d)\n", rc); 765 abort(); 766 } 767 } 768 return 0; 769 } 770 </pre> 771 772 <h2 id=example_of_a_trusted_application_client>Example of a trusted application client</h2> 773 774 <p>The following code snippets show the use of the Trusty messaging APIs to 775 implement a client of an "echo" service (shown in the code above). The <code>sync_connect()</code> 776 method shows an implementation of a synchronous connect with a timeout on top 777 of an asynchronous <code>connect()</code> call.</p> 778 779 <pre class="prettyprint"> 780 /* 781 * Local wrapper on top of an async connect that provides a 782 * synchronous connect with timeout. 783 */ 784 int sync_connect(const char *path, uint timeout) 785 { 786 int rc; 787 uevent_t evt; 788 handle_t chan; 789 790 rc = connect(path, IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT); 791 if (rc >= 0) { 792 chan = (handle_t) rc; 793 rc = wait(chan, &evt, timeout); 794 if (rc == 0) { 795 rc = ERR_BAD_STATE; 796 if (evt.handle == chan) { 797 if (evt.event & IPC_HANDLE_POLL_READY) 798 return chan; 799 if (evt.event & IPC_HANDLE_POLL_HUP) 800 rc = ERR_CHANNEL_CLOSED; 801 } 802 } 803 close(chan); 804 } 805 return rc; 806 } 807 </pre> 808 809 <p>The <code>run_end_to_end_msg_test()</code> method sends 10,000 messages asynchronously 810 to the "echo" service and handles 811 replies.</p> 812 813 <pre class="prettyprint"> 814 static int run_echo_test(void) 815 { 816 int rc; 817 handle_t chan; 818 uevent_t uevt; 819 uint8_t tx_buf[64]; 820 uint8_t rx_buf[64]; 821 ipc_msg_info_t inf; 822 ipc_msg_t tx_msg; 823 iovec_t tx_iov; 824 ipc_msg_t rx_msg; 825 iovec_t rx_iov; 826 827 /* prepare tx message buffer */ 828 tx_iov.base = tx_buf; 829 tx_iov.len = sizeof(tx_buf); 830 tx_msg.num_iov = 1; 831 tx_msg.iov = &tx_iov; 832 tx_msg.num_handles = 0; 833 tx_msg.handles = NULL; 834 835 memset (tx_buf, 0x55, sizeof(tx_buf)); 836 837 /* prepare rx message buffer */ 838 rx_iov.base = rx_buf; 839 rx_iov.len = sizeof(rx_buf); 840 rx_msg.num_iov = 1; 841 rx_msg.iov = &rx_iov; 842 rx_msg.num_handles = 0; 843 rx_msg.handles = NULL; 844 845 /* open connection to echo service */ 846 rc = sync_connect(srv_name, 1000); 847 if(rc < 0) 848 return rc; 849 850 /* got channel */ 851 chan = (handle_t)rc; 852 853 /* send/receive 10000 messages asynchronously. */ 854 uint tx_cnt = 10000; 855 uint rx_cnt = 10000; 856 857 while (tx_cnt || rx_cnt) { 858 /* send messages until all buffers are full */ 859 while (tx_cnt) { 860 rc = send_msg(chan, &tx_msg); 861 if (rc == ERR_NOT_ENOUGH_BUFFER) 862 break; /* no more space */ 863 if (rc != 64) { 864 if (rc > 0) { 865 /* incomplete send */ 866 rc = ERR_NOT_VALID; 867 } 868 goto abort_test; 869 } 870 tx_cnt--; 871 } 872 873 /* wait for reply msg or room */ 874 rc = wait(chan, &uevt, 1000); 875 if (rc != NO_ERROR) 876 goto abort_test; 877 878 /* drain all messages */ 879 while (rx_cnt) { 880 /* get a reply */ 881 rc = get_msg(chan, &inf); 882 if (rc == ERR_NO_MSG) 883 break; /* no more messages */ 884 if (rc != NO_ERROR) 885 goto abort_test; 886 887 /* read reply data */ 888 rc = read_msg(chan, inf.id, 0, &rx_msg); 889 if (rc != 64) { 890 /* unexpected reply length */ 891 rc = ERR_NOT_VALID; 892 goto abort_test; 893 } 894 895 /* discard reply */ 896 rc = put_msg(chan, inf.id); 897 if (rc != NO_ERROR) 898 goto abort_test; 899 rx_cnt--; 900 } 901 } 902 903 abort_test: 904 close(chan); 905 return rc; 906 } 907 </pre> 908 909 <h2 id=non-secure_world_apis_and_applications>Non-secure world APIs and applications</h2> 910 911 <p>A set of Trusty services, published from the secure side and marked with 912 the <code>IPC_PORT_ALLOW_NS_CONNECT</code> attribute, are accessible to kernel 913 and user space programs running on the 914 non-secure side.</p> 915 916 <p>The execution environment on the non-secure side (kernel and user space) is 917 drastically different from the execution environment on the secure-side. 918 Therefore, rather than a single library for both environments, there are two 919 different sets of APIs. In the kernel, the Client API is provided by the 920 trusty-ipc kernel driver and registers a character device node that can be used 921 by user space processes to communicate with services running on the secure 922 side.</p> 923 924 <h3 id=user_space_trusty_ipc_client_api>User space Trusty IPC Client API</h3> 925 926 <p>The user space Trusty IPC Client API library is a thin layer on top of the 927 device node <code>fd</code>.</p> 928 929 <p>A user space program starts a communication session 930 by calling <code>tipc_connect()</code>, 931 initializing a connection to a specified Trusty service. Internally, 932 the <code>tipc_connect()</code> call opens a specified device node to 933 obtain a file descriptor and invokes a <code>TIPC_IOC_CONNECT ioctl()</code> 934 call with the <code>argp</code> parameter pointing to a string containing a 935 service name to which to connect.</p> 936 937 <pre class="prettyprint"> 938 #define TIPC_IOC_MAGIC 'r' 939 #define TIPC_IOC_CONNECT _IOW(TIPC_IOC_MAGIC, 0x80, char *) 940 </pre> 941 942 <p>The resulting file descriptor can only be used to communicate with the service 943 for which it was created. The file descriptor should be closed by 944 calling <code>tipc_close()</code> when the connection is not required anymore.</p> 945 946 <p>The file descriptor obtained by the <code>tipc_connect()</code> call 947 behaves as a typical character device node; the file descriptor:</p> 948 949 <ul> 950 <li>Can be switched to non-blocking mode if needed 951 <li>Can be written to using a standard <code>write()</code> 952 call to send messages to the other side 953 <li>Can be polled (using <code>poll()</code> calls or <code>select()</code> calls) 954 for availability of incoming messages as a regular file descriptor 955 <li>Can be read to retrieve incoming messages 956 </ul> 957 958 <p>A caller sends a message to the Trusty service by executing a write call for 959 the specified <code>fd</code>. All data passed to the above <code>write()</code> call 960 is transformed into a message by the trusty-ipc driver. The message is 961 delivered to the secure side where the data is handled by the IPC subsystem in 962 the Trusty kernel and routed to the proper destination and delivered to an app 963 event loop as an <code>IPC_HANDLE_POLL_MSG</code> event on a particular channel 964 handle. Depending on the particular, 965 service-specific protocol, the Trusty service may send one or more reply 966 messages that are delivered back to the non-secure side and placed in the 967 appropriate channel file descriptor message queue to be retrieved by the user 968 space application <code>read()</code> call.</p> 969 970 <h4 id=tipc_connect>tipc_connect()</h4> 971 972 <p>Opens a specified <code>tipc</code> device node and initiates a 973 connection to a specified Trusty service.</p> 974 975 <pre class="prettyprint"> 976 int tipc_connect(const char *dev_name, const char *srv_name); 977 </pre> 978 979 <p>[in] <code>dev_name</code>: Path to the Trusty IPC device node to open</p> 980 981 <p>[in] <code>srv_name</code>: Name of a published Trusty service to which to connect</p> 982 983 <p>[retval]: Valid file descriptor on success, -1 otherwise.</p> 984 985 <h4 id=tipc_close>tipc_close()</h4> 986 987 <p>Closes the connection to the Trusty service specified by a file descriptor.</p> 988 989 <pre class="prettyprint"> 990 int tipc_close(int fd); 991 </pre> 992 993 <p>[in] <code>fd</code>: File descriptor previously opened by 994 a <code>tipc_connect()</code> call</p> 995 996 <h2 id=kernel_trusty_ipc_client_api>Kernel Trusty IPC Client API</h2> 997 998 <p>The kernel Trusty IPC Client API is available for kernel drivers. The user 999 space Trusty IPC API is implemented on top of this API.</p> 1000 1001 <p>In general, typical usage of this API consists of a caller creating 1002 a <code>struct tipc_chan</code> object by using the <code>tipc_create_channel()</code> 1003 function and then using the <code>tipc_chan_connect()</code> call to initiate a 1004 connection to the Trusty IPC service running on the secure 1005 side. The connection to the remote side can be terminated by 1006 calling <code>tipc_chan_shutdown()</code> followed by 1007 <code>tipc_chan_destroy()</code> to clean up resources.</p> 1008 1009 <p>Upon receiving a notification (through the <code>handle_event()</code> callback) 1010 that a connection has been successfully established, a caller does 1011 the following:</p> 1012 1013 <ul> 1014 <li>Obtains a message buffer using the <code>tipc_chan_get_txbuf_timeout()</code> call 1015 <li>Composes a message, and 1016 <li>Queues the message using the <code>tipc_chan_queue_msg()</code> 1017 method for delivery to a Trusty service (on the secure side), to which the 1018 channel is connected 1019 </ul> 1020 1021 <p>After queueing is successful, the caller should forget the message buffer 1022 because the message buffer eventually returns to the free buffer pool after 1023 processing by the remote side (for reuse later, for other messages). The user 1024 only needs to call <code>tipc_chan_put_txbuf()</code> if it fails to 1025 queue such buffer or it is not required anymore.</p> 1026 1027 <p>An API user receives messages from the remote side by handling a 1028 <code>handle_msg()</code> notification callback (which is called in 1029 the context of the trusty-ipc <code>rx</code> workqueue) that 1030 provides a pointer to an <code>rx</code> buffer containing an 1031 incoming message to be handled.</p> 1032 1033 <p>It is expected that the <code>handle_msg()</code> callback 1034 implementation will return a pointer to a valid <code>struct tipc_msg_buf</code>. 1035 It can be the same as the incoming message buffer if it is handled locally 1036 and not required anymore. Alternatively, it can be a new buffer obtained by 1037 a <code>tipc_chan_get_rxbuf()</code> call if the incoming buffer is queued 1038 for further processing. A detached <code>rx</code> buffer must be tracked 1039 and eventually released using a <code>tipc_chan_put_rxbuf()</code> call when 1040 it is no longer needed.</p> 1041 1042 <h3 id=methods_ktic_api>Methods in the Kernel Trusty IPC Client API</h3> 1043 1044 <h4 id=tipc_create_channel>tipc_create_channel()</h4> 1045 1046 <p>Creates and configures an instance of a Trusty IPC channel for a particular 1047 trusty-ipc device.</p> 1048 1049 <pre class="prettyprint"> 1050 struct tipc_chan *tipc_create_channel(struct device *dev, 1051 const struct tipc_chan_ops *ops, 1052 void *cb_arg); 1053 </pre> 1054 1055 <p>[in] <code>dev</code>: Pointer to the trusty-ipc for which the device 1056 channel is created</p> 1057 1058 <p>[in] <code>ops</code>: Pointer to a <code>struct tipc_chan_ops</code>, 1059 with caller-specific 1060 callbacks filled in</p> 1061 1062 <p>[in] <code>cb_arg</code>: Pointer to data that will be passed 1063 to <code>tipc_chan_ops</code> callbacks</p> 1064 1065 <p>[retval]: Pointer to a newly-created instance of 1066 <code>struct tipc_chan</code> on success, 1067 <code>ERR_PTR(err)</code> otherwise</p> 1068 1069 <p>In general, a caller must provide two callbacks that are asynchronously invoked 1070 when the corresponding activity is occurring.</p> 1071 1072 <p>The <code>void (*handle_event)(void *cb_arg, int event)</code>event is invoked 1073 to notify a caller about a channel state change.</p> 1074 1075 <p>[in] <code>cb_arg</code>: Pointer to data passed to a 1076 <code>tipc_create_channel()</code> call</p> 1077 1078 <p>[in] <code>event</code>: An event that can be one of the following values:</p> 1079 1080 <ul> 1081 <li><code>TIPC_CHANNEL_CONNECTED</code> - indicates a successful connection 1082 to the remote side 1083 <li><code>TIPC_CHANNEL_DISCONNECTED</code> - indicates the remote side denied the 1084 new connection request or requested 1085 disconnection for the previously connected channel 1086 <li><code>TIPC_CHANNEL_SHUTDOWN</code> - indicates the remote side is shutting down, 1087 permanently terminating all connections 1088 </ul> 1089 1090 <p>The <code>struct tipc_msg_buf *(*handle_msg)(void *cb_arg, struct tipc_msg_buf *mb)</code> 1091 callback is invoked to provide notification that a new message has been 1092 received over a specified channel:</p> 1093 1094 <ul> 1095 <li>[in] <code>cb_arg</code>: Pointer to data passed to the 1096 <code>tipc_create_channel()</code> call 1097 <li>[in] <code>mb</code>: Pointer to a <code>struct tipc_msg_buf</code> 1098 describing an incoming message 1099 <li>[retval]: The callback implementation is expected to return a pointer to a 1100 <code>struct tipc_msg_buf</code> that can be the same pointer received 1101 as an 1102 <code>mb</code> parameter if the message is handled locally and is not 1103 required anymore (or it 1104 can be a new buffer obtained by the <code>tipc_chan_get_rxbuf()</code> call) 1105 </ul> 1106 1107 <h4 id=tipc_chan_connect>tipc_chan_connect()</h4> 1108 1109 <p>Initiates a connection to the specified Trusty IPC service.</p> 1110 1111 <pre class="prettyprint"> 1112 int tipc_chan_connect(struct tipc_chan *chan, const char *port); 1113 </pre> 1114 1115 <p>[in] <code>chan</code>: Pointer to a channel returned by the 1116 <code>tipc_create_chan()</code> call</p> 1117 1118 <p>[in] <code>port</code>: Pointer to a string containing the 1119 service name to which to connect</p> 1120 1121 <p>[retval]: 0 on success, a negative error otherwise</p> 1122 1123 <p>The caller is notified when a connection is established by receiving a 1124 <code>handle_event</code> callback.</p> 1125 1126 <h4 id=tipc_chan_shutdown>tipc_chan_shutdown()</h4> 1127 1128 <p>Terminates a connection to the Trusty IPC service previously initiated 1129 by a <code>tipc_chan_connect()</code> call.</p> 1130 1131 <pre class="prettyprint"> 1132 int tipc_chan_shutdown(struct tipc_chan *chan); 1133 </pre> 1134 1135 <p>[in] <code>chan</code>: Pointer to a channel returned by 1136 a <code>tipc_create_chan()</code> call</p> 1137 1138 <h4 id=tipc_chan_destroy>tipc_chan_destroy()</h4> 1139 1140 <p>Destroys a specified Trusty IPC channel.</p> 1141 1142 <pre class="prettyprint"> 1143 void tipc_chan_destroy(struct tipc_chan *chan); 1144 </pre> 1145 1146 <p>[in] <code>chan</code>: Pointer to a channel returned by the 1147 <code>tipc_create_chan()</code> call</p> 1148 1149 <h4 id=tipc_chan_get_txbuf_timeout>tipc_chan_get_txbuf_timeout()</h4> 1150 1151 <p>Obtains a message buffer that can be used to send data over a specified 1152 channel. If the buffer is not immediately available the caller may be blocked 1153 for the specified timeout (in milliseconds).</p> 1154 1155 <pre class="prettyprint"> 1156 struct tipc_msg_buf * 1157 tipc_chan_get_txbuf_timeout(struct tipc_chan *chan, long timeout); 1158 </pre> 1159 1160 <p>[in] <code>chan</code>: Pointer to the channel to which to queue a message</p> 1161 1162 <p>[in] <code>chan</code>: Maximum timeout to wait until the 1163 <code>tx</code> buffer becomes available </p> 1164 1165 <p>[retval]: A valid message buffer on success, 1166 <code>ERR_PTR(err)</code> on error</p> 1167 1168 <h4 id=tipc_chan_queue_msg>tipc_chan_queue_msg()</h4> 1169 1170 <p>Queues a message to be sent over the specified 1171 Trusty IPC channels.</p> 1172 1173 <pre class="prettyprint"> 1174 int tipc_chan_queue_msg(struct tipc_chan *chan, struct tipc_msg_buf *mb); 1175 </pre> 1176 1177 <p>[in] <code>chan</code>: Pointer to the channel to which to queue the message</p> 1178 1179 <p>[in] <code>mb:</code> Pointer to the message to queue 1180 (obtained by a <code>tipc_chan_get_txbuf_timeout()</code> call)</p> 1181 1182 <p>[retval]: 0 on success, a negative error otherwise</p> 1183 1184 <h4 id=tipc_chan_put_txbuf>tipc_chan_put_txbuf()</h4> 1185 1186 <p>Releases the specified <code>Tx</code> message buffer 1187 previously obtained by a <code>tipc_chan_get_txbuf_timeout()</code> call.</p> 1188 1189 <pre class="prettyprint"> 1190 void tipc_chan_put_txbuf(struct tipc_chan *chan, 1191 struct tipc_msg_buf *mb); 1192 </pre> 1193 1194 <p>[in] <code>chan</code>: Pointer to the channel to which 1195 this message buffer belongs</p> 1196 1197 <p>[in] <code>mb</code>: Pointer to the message buffer to release</p> 1198 1199 <p>[retval]: None</p> 1200 1201 <h4 id=tipc_chan_get_rxbuf>tipc_chan_get_rxbuf()</h4> 1202 1203 <p>Obtains a new message buffer that can be used to receive messages over the 1204 specified channel.</p> 1205 1206 <pre class="prettyprint"> 1207 struct tipc_msg_buf *tipc_chan_get_rxbuf(struct tipc_chan *chan); 1208 </pre> 1209 1210 <p>[in] <code>chan</code>: Pointer to a channel to which this message buffer belongs</p> 1211 1212 <p>[retval]: A valid message buffer on success, <code>ERR_PTR(err)</code> on error</p> 1213 1214 <h4 id=tipc_chan_put_rxbuf>tipc_chan_put_rxbuf()</h4> 1215 1216 <p>Releases a specified message buffer previously obtained by a 1217 <code>tipc_chan_get_rxbuf()</code> call.</p> 1218 1219 <pre class="prettyprint"> 1220 void tipc_chan_put_rxbuf(struct tipc_chan *chan, 1221 struct tipc_msg_buf *mb); 1222 </pre> 1223 1224 <p>[in] <code>chan</code>: Pointer to a channel to which this message buffer belongs</p> 1225 1226 <p>[in] <code>mb</code>: Pointer to a message buffer to release</p> 1227 1228 <p>[retval]: None</p> 1229 1230 </body> 1231 </html> 1232