blob: 8a8c8a4487b3af3090df670d96364802f1043c91 [file] [log] [blame]
Julian Halle76ade82020-11-25 03:07:21 +01001Service Access Protocols
2========================
3
4A trusted service is accessed by calling service-specific methods via an RPC mechanism. The set of callable methods forms the
5public interface exposed by a service. This section is concerned with interface conventions and protocols used for serializing
6method parameters and return values. It is anticipated that there will be a need to support different parameter serialization
7schemes to suite different needs. The project accommodates this with the following:
8
9 - The Protocols directory structure allows for different protocol definitions for the same service.
10 - Message serialization code is decoupled from service provider code using an abstract 'serializer' interface. Alternative
11 concrete serializers may provide implementations of the interface.
12
Julian Halle76ade82020-11-25 03:07:21 +010013A deployment independent interface for locating services and establishing RPC sessions is described here: :ref:`Service Locator`
14
Imre Kis9df392c2023-09-14 13:29:09 +020015Trusted Services protocol layers
16--------------------------------
17
18.. image:: image/TSProtocolLayers.svg
19
20* Service client interface: This component provides the interface to a given service for a user application, i.e. the PSA
21 Crypto, Internal Trusted Storage, etc. interface.
22
23* Service layer: This layer is responsible for serializing and deserializing the service specific parameters and it provides
24 a transparent interface between the caller and endpoint side.
25
26* RPC layer:
27
28 * RPC caller session: This component provides a session-like object for the service layer. After opening the session, it is
29 tied to the opened service interface of the endpoint. Each service call can use the simple begin/invoke/end interface for
30 requesting a buffer for the call parameters, for invoking the call and for releasing the response buffer.
31
32 The RPC caller session manages the lifetime of the shared memory. Currently it has two options. It either creates the
33 memory on session open and keeps it while the session is open, or it creates the shared buffer for each call and releases
34 it when the call ends (``end()``).
35
36 * RPC caller implementations (`ts_rpc_caller_linux`, `ts_rpc_caller_sp`, etc.): The RPC caller session is built on the
37 primitives of the RPC callers. These primitives allow the caller session finding the remote endpoint, creating and
38 releasing shared memories and doing the actual call.
39
40 The main RPC implementation is the TS RPC which is a TS specific RPC solution over FF-A. The project contains caller
41 implementations for Linux and for S-EL0 SPs. The Linux implementation is split between the user space and a kernel driver.
42
43 There are other RPC caller implementations (dummy, direct) which are used for testing purposes.
44
45 * RPC endpoint (`ts_rpc_endpoint_sp`): This component provides the RPC endpoint which can host multiple services. Once it
46 receives the call from the client, it finds the matching service and forwards the serialized call parameters to it.
47
48* FF-A layer: It is the transport layer of the protocol stack, and it provides interfaces for sending messages and sharing
49 memory between normal world and secure world components.
50
51TS RPC implementation
52---------------------
53
54Generic concepts
55''''''''''''''''
56
57* The requests are always sent by the caller and the endpoint sends a response.
58* The protocol version describes the ABI, the allowed values of the message fields and the behavior of the calls.
59* Service endpoints are provided by FF-A secure partitions.
60* Each endpoint can implement multiple services. The services are identified by their service UUID (**not** FF-A UUID). To
61 avoid including the UUID in each service call, a short interface ID is assigned to each service. The mapping of service
62 UUIDs and interface IDs can be queried by an RPC call. The lifetime of the interface ID is the same as the lifetime of the
63 service. The `0xff` interface ID is used for the management interface.
64* The service calls use shared memory to forward the call payload. It has to be shared via FF-A and then retrieved by the
65 endpoint. The shared memories are tied to an endpoint not to a service.
66* The errors which happen in the RPC layer will result in a RPC status code which indicates an error.
67* The errors which happen in the service handler will result in a service status code which indicates an error. In this case
68 the RPC status code will be `RPC_SUCCESS` as the RPC layer was able to forward the call between the service caller and the
69 service handler.
70
71ABI
72'''
73
74The ABI of the TS RPC protocol uses the 32 bit variants of ``FFA_MSG_SEND_DIRECT_REQ`` and ``FFA_MSG_SEND_DIRECT_RESP``
75interfaces of the FF-A specification. The use of the implementation specific arguments is listed in the table below.
76
77.. list-table:: TS RPC ABI
78 :header-rows: 1
79
80 * - Message name
81 - Short message ID
82 - W3[31:30] - SAP
83 - W3[29:24] - Flags
84 - W3[23:16] - Interface ID
85 - W3[15:0] - Opcode
86 - W4 - Arg1
87 - W5 - Arg2
88 - W6 - Arg3
89 - W7 - Arg4
90 * - RPC protocol version get request
91 - ``VERSION_GET``
92 - ``0b00``
93 - ``0b000000``
94 - ``0xff``
95 - ``0x0000``
96 - Reserved (MBZ)
97 - Reserved (MBZ)
98 - Reserved (MBZ)
99 - Reserved (MBZ)
100 * - RPC protocol version get response
101 - ``VERSION_GET``
102 - ``0b00``
103 - ``0b000000``
104 - ``0xff``
105 - ``0x0000``
106 - Version, starting from ``0x00000001``
107 - Reserved (MBZ)
108 - Reserved (MBZ)
109 - Reserved (MBZ)
110 * - Memory retrieve request
111 - ``MEM_RETRIEVE``
112 - ``0b00``
113 - ``0b000000``
114 - ``0xff``
115 - ``0x0001``
116 - FF-A memory handle LSW
117 - FF-A memory handle MSW
118 - FF-A memory tag LSW
119 - FF-A memory tag MSW
120 * - Memory relinquish request
121 - ``MEM_RELINQUISH``
122 - ``0b00``
123 - ``0b000000``
124 - ``0xff``
125 - ``0x0002``
126 - FF-A memory handle LSW
127 - FF-A memory handle MSW
128 - Reserved (MBZ)
129 - Reserved (MBZ)
130 * - Memory retrieve/relinquish response
131 - ``MEM_RETRIEVE``/``MEM_RELINQUISH``
132 - ``0b00``
133 - ``0b000000``
134 - ``0xff``
135 - ``0x0001``/``0x0002``
136 - TS RPC status
137 - Reserved (MBZ)
138 - Reserved (MBZ)
139 - Reserved (MBZ)
140 * - Service info get request
141 - ``SERVICE_INFO_GET``
142 - ``0b00``
143 - ``0b000000``
144 - ``0xff``
145 - ``0x0003``
146 - Service UUID
147 - Service UUID
148 - Service UUID
149 - Service UUID
150 * - Service info get response
151 - ``SERVICE_INFO_GET``
152 - ``0b00``
153 - ``0b000000``
154 - ``0xff``
155 - ``0x0003``
156 - TS RPC status
157 - ``[31:8]`` Reserved
158
159 ``[7:0]`` Queried service interface ID
160 - Reserved (MBZ)
161 - Reserved (MBZ)
162 * - Service call request
163 -
164 - ``0b00``
165 - ``0b000000``
166 - Service interface ID
167 - Service opcode
168 - FF-A memory handle LSW
169 - FF-A memory handle MSW
170 - Request length
171 - Client ID
172 * - Service call response
173 -
174 - ``0b00``
175 - ``0b000000``
176 - Service interface ID
177 - Service opcode
178 - TS RPC status
179 - Service status
180 - Response length
181 - Reserved
182
183* **RPC protocol version get**
184
185 Queries the RPC protocol version. This message must be available and backwards compatible for all protocol versions.
186
187* **Memory retrieve**
188
189 Requests the endpoint to do an ``FFA_MEM_RETRIEVE_REQ`` call using the forwarded FF-A memory handle and tag.
190
191* **Memory relinquish**
192
193 Requests the endpoint to do an ``FFA_MEM_RELINQUISH`` call using the forwarded FF-A memory handle.
194
195* **Service info get**
196
197 Query service information from the endpoint by the UUID of the service. The UUID is transmitted as defined in SMCCC section
198 5.3 but in registers W4-W7. The returned service interface ID should be used in the service calls. Multiple endpoints can
199 implement the same service but one endpoint can implement a service only once.
200
201* **Service call**
202
203 After creating a shared memory and querying the interface ID for a given service UUID the caller can make a service call. The
204 service opcode and the contents of the shared memory is service specific. The request and response length fields indicate the
205 used area of the shared memory.
206
207 It is allowed to do a limited service call without shared memory, i.e. doorbell call. In this case the FF-A memory ID has to
208 be the invalid handle value ``0xffffffffffffffff``.
209
210Service discovery
211'''''''''''''''''
212
213* Query all TS SPs via ``FFA_PARTITION_INFO_GET`` call made to the SPMC. All TS SPs have the same FF-A UUID:
214 ``bdcd76d7-825e-4751-963b-86d4f84943ac`` If the system setup has fixed SP endpoint IDs, this step can be skipped.
215* Iterate thought the TS SPs and make a "Service info get request" RPC call to the SPs, containing the service UUID. If the
216 RPC status in the "Service info get response" is `RPC_SUCCESS`, the SP implements the service and its interface ID is returned
217 in the response.
218* If there are multiple instances of a service, the selection between these should be done in a service specific way (i.e.
219 query service version, capabilities, etc.).
220
221.. image:: image/TSServiceDiscovery.svg
222
223RPC status code values
224'''''''''''''''''''''''
225
226The status codes for the RPC layer are defined in `components/rpc/common/interface/rpc_status.h`. Currently the following values
227are defined:
228
229.. literalinclude:: ../../components/rpc/common/interface/rpc_status.h
230 :lines: 20-32
231 :language: C
232
233Example TS RPC call
234'''''''''''''''''''
235
236This example shows the full sequence of a service call by opening the RPC session, doing the call (begin/invoke/end) and then
237closing the session. In this case the RPC session it set to create individual shared memory for each call.
238
239.. uml:: uml/TSRPCCall.puml
240
241.. note::
242 Although the TS RPC layer messages use ``FFA_MSG_SEND_DIRECT_REQ``/``FFA_MSG_SEND_DIRECT_RESP`` interface and go through the
243 SPMC their destination is not the SPMC but the RPC endpoint. For simplifying the diagram, these calls are showed as direct
244 calls between the TS RPC caller and the TS RPC endpoint.
245
Julian Halle76ade82020-11-25 03:07:21 +0100246Status Codes
247------------
248
Imre Kis9df392c2023-09-14 13:29:09 +0200249On returning from a request to invoke a service method, two status codes are returned:
Julian Halle76ade82020-11-25 03:07:21 +0100250
251 - *RPC status* - A generic status code that corresponds to the RPC call transaction. RPC status codes are standardized across
Imre Kis9df392c2023-09-14 13:29:09 +0200252 all services. (See: `RPC status code values`_)
253 - *Service status* - a service specific status code. (See: `Service Status Codes`_ )
Julian Halle76ade82020-11-25 03:07:21 +0100254
255Separation of status codes by layer allows service specific status codes to be accommodated while keeping RPC status codes
256common.
257
Imre Kis9df392c2023-09-14 13:29:09 +0200258A client should only check the returned service status if the returned RPC status value is `RPC_SUCCESS`. All other RPC
259status values indicate that an error occurred in delivering the RPC request. An RPC status of `RPC_SUCCESS` does not
260indicate that the service was successful. It merely indicates that the request was delivered, a suitable handler was
Julian Halle76ade82020-11-25 03:07:21 +0100261identified and the request parameters were understood.
262
263Service Access Protocol Definition Conventions
264----------------------------------------------
265
266A service access protocol defines the following:
267
268 - Opcodes used for identifying service methods.
269 - Request parameters for each method.
270 - Response parameters for method return values.
271 - Operation status code.
272
273Details of how public interface definition files for trusted services are organized, see: :ref:`Project Structure`
274
275It is possible that for certain deployments, it will be necessary to customize which parameter encoding scheme is used. Many
276schemes are possible such as Protocol Buffers, CBOR, JSON, TLV, TPM commands or packed C structures. To make scheme
Imre Kis9df392c2023-09-14 13:29:09 +0200277customization straight forward, serialize/deserialize operations should be encapsulated behind a common interface to decouple
Julian Halle76ade82020-11-25 03:07:21 +0100278service provider code from any particular serialization scheme. A section below describes a pattern for achieving this.
279
280Service Namespace
281'''''''''''''''''
282
283Definitions that form a service access protocol should live within a namespace that is unique for the particular service. Using
284a namespace for service definitions avoids possible clashes between similarly named definitions that belong to different
285services. How the namespace is implemented depends on how the access protocol is defined. For example, the Protocol Buffers
286definitions for the crypto service all live within the ts_crypto package. The recommended convention for forming a trusted
287service namespace is as follows::
288
289 ts_<service_name>
290
291 e.g.
292 ts_crypto
293 ts_secure_storage
294
295Language Independent Protocol Definitions
296'''''''''''''''''''''''''''''''''''''''''
297
298By defining service access protocols using an interface description language (IDL) with good support for different programming
299languages, it should be straight forward to access trusted services from clients written in a range of languages. On Arm
300Cortex-A deployments, it is common for user applications to be implemented using a range of languages such as Go, Python or
301Java. Rather than relying on a binding to a C client library, native client code may be generated from the formal protocol
302definition files. Initial protocol definitions use Google Protocol Buffers as the IDL. The project structure allows for use of
303alternative definition schemes and serializations.
304
305Opcode Definition
306`````````````````
307
308Opcodes are integer values that identify methods implemented by a service endpoint. Opcodes only need to be unique within the
309scope of a particular service. The mapping of opcode to method is an important part of a service interface definition and
310should be readily available to clients written in a variety of programming languages. For a Protocol Buffers based definition,
311opcodes are defined in a file called::
312
313 opcodes.proto
314
315For example, for the Crypto trusted service, the Protocol Buffers opcode definitions are in::
316
317 protocols/service/crypto/protobuf/opcodes.proto
318
319Alternative definitions for light-weight C clients using the packed-c scheme are in::
320
321 protocols/service/crypto/packed-c/opcodes.h
322
323Parameter Definition
324````````````````````
325
326The convention used for serializing method parameters and return values may be specific to a particular service. The definition
327file will include message definitions for both request and response parameters. Common objects that are used for multiple
328methods should be defined in separate files. When using Protobufs, the following naming convention for method parameter files
329should be used::
330
331 <method_name>.proto
332
333For example, the Crypto export_public_key method is defined in a file called::
334
335 protocols/service/crypto/protobuf/export_public_key.proto
336
Julian Halle76ade82020-11-25 03:07:21 +0100337Service Status Codes
338````````````````````
339
340Service specific status code definitions using different definition schemes are defined here (using crypto service as an
341example)::
342
343 protocols/service/crypto/protobuf/status.proto
344 protocols/service/crypto/packed-c/status.h
345
346Status code definitions may also be shared between services. For example, services that conform to PSA API conventions will use
347standardized PSA status codes, defined here::
348
349 protocols/service/psa/protobuf/status.proto
350 protocols/service/psa/packed-c/status.h
351
352Use of Protocol Buffers
353-----------------------
354
355When Protocol Buffers is used for protocol definition and parameter serialization, the following conventions have been adopted.
356
357.proto File Style Guide
358'''''''''''''''''''''''
359
360The style of the .proto files should follow Google's Protocol Buffers Style Guide.
361
362Protocol Buffer Library for Trusted Services
363''''''''''''''''''''''''''''''''''''''''''''
364
365Protocol Buffers standardizes how service interfaces are defined and the on-wire encoding for messages. Because of this, service
366clients and service providers are free to use any conformant implementation. However for trusted services that may be deployed
367across a range of environments, some of which may be resource constrained, a lightweight library should be used for C/C++ code
368that implement or use trusted services. For this purpose, Nanobp (https://github.com/nanopb/nanopb) should be used.
369
370Serialization Protocol Flexibility
371----------------------------------
372
373Many different serialization protocols exist for encoding and decoding message parameters. Hard-wiring a particular protocol
374into a trusted service provider implementation isn't desirable for the following reasons:
375
376 - Depending on the complexity of serialization operations, mixing serialization logic with protocol-independent code makes
377 trusted service provider code bigger and more difficult to maintain.
378 - Different protocols may be needed for different deployments. It should be possible to make a build-time or even a
379 run-time selection of which protocol to use.
380 - The number of supported serializations protocols is likely to grow. Adding a new protocol shouldn't require you to make
381 extensive code changes and definitely shouldn't break support for existing protocols.
382
383These problems can be avoided by implementing protocol specific operations behind a common interface. Serialize/deserialize
384operations will have the following pattern::
385
386 int serialize_for_method(msg_buffer *buf, in args...);
387 int deserialize_for_method(const msg_buffer *buf, out args...);
388
Imre Kis9df392c2023-09-14 13:29:09 +0200389Encoding types are represented as dedicated service interfaces in the RPC protocol and as such are identified by a uniq
390service UUID.
Julian Halle76ade82020-11-25 03:07:21 +0100391
392--------------
393
Imre Kis9df392c2023-09-14 13:29:09 +0200394*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
Julian Halle76ade82020-11-25 03:07:21 +0100395
396SPDX-License-Identifier: BSD-3-Clause