blob: 9a5663daa1bdfb131b5c7f7ba81e8ecec5c930b4 [file] [log] [blame]
Edison Ai1b7e8452019-12-16 10:03:52 +08001#######################
2Adding Secure Partition
3#######################
4
Edison Ai1b7e8452019-12-16 10:03:52 +08005***********************
6Terms and abbreviations
7***********************
8This document uses the following terms and abbreviations.
9
10.. table:: term table
11 :widths: auto
12
13 ================== ==================================
14 **Term** **Meaning**
15 ================== ==================================
16 FF Firmware Framework
17 ID Identifier
18 IPC Interprocess communication
19 IPC model The secure IPC framework
20 irqs Interrupt requests
21 Library model The secure function call framework
22 MMIO Memory Mapped I/O
23 PSA Platform Security Architecture
24 RoT Root of Trust
25 SID RoT Service ID
26 SP Secure Partition
27 SPM Secure Partition Manager
28 TF-M Trusted firmware M
29 ================== ==================================
30
31************
32Introduction
33************
34Secure Partition is an execution environment that provides the following
35functions to Root of Trust (RoT) Services:
36
37- Access to resources, protection of its own code and data.
38- Mechanisms to interact with other components in the system.
39
40Each Secure Partition is a single thread of execution and the smallest unit of
41isolation.
42
43This document mainly describes how to add a secure partition in TF-M and
44focuses on the configuration, manifest, implement rules. The actual
45source-level implementation is not included in this document.
46
47.. Note::
48 If not otherwise specified, the steps are identical for library and IPC
49 model.
50
51 The IPC model conforms the *PSA Firmware Framework (FF) v 1.0.0*. Refer to
52 `PSA Firmware Framework specification`_ for details.
53
54*******
55Process
56*******
57The main steps to add a secure partition are as follows:
58
59- `Add source folder`_
60- `Add manifest`_
61- `Add configuration`_
62- `Generate files`_
63- `Implement the RoT services`_
64
65Add source folder
66=================
Ken Liu738a4b02020-06-04 14:52:38 +080067Add a source folder under ``<TF-M base folder>/secure_fw/partitions`` for the new
Edison Ai1b7e8452019-12-16 10:03:52 +080068secure partition (Let's take EXAMPLE as the folder name):
69
70This folder should include those parts:
71
72- Manifest file: EXAMPLE.yaml
73- CMake configuration files
74- Source code files
75
76Add manifest
77============
78Each Secure Partition must have resource requirements declared in a manifest
79file. The Secure Partition Manager (SPM) uses the manifest file to assemble and
80allocate resources within the SPE. The manifest includes the following:
81
82- A Secure Partition name.
83- A list of implemented RoT Services.
84- Access to other RoT Services.
85- Memory requirements.
86- Scheduling hints.
87- Peripheral memory-mapped I/O regions and interrupts.
88
89.. Note::
90 The current manifest format in TF-M is "yaml" which is different from the
91 requirement of PSA FF.
92
93Here is a manifest reference example for the IPC model, please refer to
94`Library model support`_ for the library extend:
95
96.. code-block:: yaml
97
98 {
99 "psa_framework_version": 1.0,
100 "name": "TFM_SP_EXAMPLE",
101 "type": "PSA-ROT",
102 "priority": "HIGH",
Boris Deleticfb231172020-08-06 22:46:53 +0100103 "entry_point": "example_main",
Edison Ai1b7e8452019-12-16 10:03:52 +0800104 "stack_size": "0x0200",
105 "services" : [
106 {
107 "name": "ROT_A",
108 "sid": "0x0000F000",
109 "non_secure_clients": true,
110 "version": 1,
111 "version_policy": "STRICT"
112 }
113 ],
114 "mmio_regions": [
115 {
116 "name": "TFM_PERIPHERAL_A",
117 "permission": "READ-WRITE"
118 }
119 ],
120 "irqs": [
121 {
122 "source": "TFM_A_IRQ",
123 "signal": "SPM_CORE_A_IRQ",
124 "tfm_irq_priority": 64,
125 }
126 ],
127 "linker_pattern": {
128 "object_list": [
129 "*EXAMPLE.*"
130 ]
131 }
132 }
133
134Secure Partition ID Distribution
135--------------------------------
136Every Secure Partition has an identifier (ID). TF-M will generate a header file
137that includes definitions of the Secure Partition IDs. The header file is
138``<TF-M base folder>/interface/include/psa_manifest/pid.h``. Each definition
139uses the ``name`` attribute in the manifest as its name and the value is
140allocated by SPM.
141
142.. code-block:: c
143
144 #define name id-value
145
146Here is the Secure Partition ID table used in TF-M.
147
148.. table:: PID table
149 :widths: auto
150
151 =============================== =================
152 **Partition name** **Partition ID**
153 =============================== =================
154 Reserved 0-255
Kevin Pengc6d74502020-03-04 16:55:37 +0800155 TFM_SP_PS 256
Edison Ai1b7e8452019-12-16 10:03:52 +0800156 TFM_SP_ITS 257
157 TFM_SP_AUDIT_LOG 258
158 TFM_SP_CRYPTO 259
159 TFM_SP_PLATFORM 260
160 TFM_SP_INITIAL_ATTESTATION 261
161 TFM_SP_CORE_TEST 262
162 TFM_SP_CORE_TEST_2 263
163 TFM_SP_SECURE_TEST_PARTITION 264
164 TFM_SP_IPC_SERVICE_TEST 265
165 TFM_SP_IPC_CLIENT_TEST 266
166 TFM_IRQ_TEST_1 267
Kevin Pengc6d74502020-03-04 16:55:37 +0800167 TFM_SP_PS_TEST 268
Edison Ai1b7e8452019-12-16 10:03:52 +0800168 =============================== =================
169
170About where to add the definition, please refer to the chapter `Add
171configuration`_.
172
173RoT Service ID (SID) Distribution
174---------------------------------
175An RoT Service is identified by its RoT Service ID (SID). A SID is a 32-bit
176number that is associated with a symbolic name in the Secure Partition
177manifest. The bits [31:12] uniquely identify the vendor of the RoT Service.
178The remaining bits [11:0] can be used at the discretion of the vendor.
179
180Here is the RoT Service ID table used in TF-M.
181
182.. table:: SID table
183 :widths: auto
184
185 =========================== ====================== ========================
186 **Services** **Vendor ID(20 bits)** **Function ID(12 bits)**
187 =========================== ====================== ========================
188 audit_logging 0x00000 0x000-0x01F
189 initial_attestation 0x00000 0x020-0x03F
190 platform 0x00000 0x040-0x05F
Kevin Pengc6d74502020-03-04 16:55:37 +0800191 protected_storage 0x00000 0x060-0x07F
Edison Ai1b7e8452019-12-16 10:03:52 +0800192 crypto 0x00000 0x080-0x09F
193 internal_trusted_storage 0x00000 0x0A0-0x0BF
194 test_secure_service 0x0000F 0x000-0x01F
195 core_test 0x0000F 0x020-0x03F
196 core_test_2 0x0000F 0x040-0x05F
197 tfm_ipc_client 0x0000F 0x060-0x07F
198 tfm_ipc_service 0x0000F 0x080-0x09F
199 tfm_irq_test_service_1 0x0000F 0x0A0-0x0BF
Kevin Pengc6d74502020-03-04 16:55:37 +0800200 tfm_ps_test_service 0x0000F 0x0C0-0x0DF
Edison Ai1b7e8452019-12-16 10:03:52 +0800201 =========================== ====================== ========================
202
203mmio_regions
204------------
205This attribute is a list of MMIO region objects which the Secure Partition
206needs access to. TF-M only supports the ``named_region`` current. Please refer
207to PSA FF for more details about it. The user needs to provide a name macro to
208indicate the variable of the memory region.
209
210TF-M uses the below structure to indicate a peripheral memory.
211
212.. code-block:: c
213
214 struct tfm_spm_partition_platform_data_t {
215 uint32_t periph_start;
216 uint32_t periph_limit;
217 int16_t periph_ppc_bank;
218 int16_t periph_ppc_loc;
219 };
220
221.. Note::
222 This structure is not expected by TF-M, it's only that the current
223 implementations are using. Other peripherals that need different information
224 to create isolation need to define a different structure with the same name.
225
226Here is a example for it:
227
228.. code-block:: c
229
230 struct tfm_spm_partition_platform_data_t tfm_peripheral_A;
231 #define TFM_PERIPHERAL_A (&tfm_peripheral_A)
232
233linker_pattern
234--------------
235``linker_pattern`` is a legacy region which contains the minimum information
236required to link a Secure Partition’s compiled static objects. Now, it is
237required as 'IMPLEMENTATION DEFINED' in PSA FF 1.0.0.
238
239Library model support
240---------------------
241For the library model, the user needs to add a ``secure_functions`` item. The
242main difference between ``secure_function`` and ``services`` is the extra
243``signal`` key for secure function entry.
244
245The ``signal`` must be the upper case of the secure function name.
246
247.. code-block:: yaml
248
249 "secure_functions": [
250 {
251 "name": "TFM_EXAMPLE_A",
252 "signal": "EXAMPLE_A_FUNC",
253 "sid": "0x00000000",
254 "non_secure_clients": true,
255 "version": 1,
256 "version_policy": "STRICT"
257 },
258
259Add configuration
260=================
261The following configuration tasks are required for the newly added secure
262partition:
263
264Add CMake configure files
265-------------------------
266Two CMake configure files need to be added:
267
268- CMakeLists.inc, which is used to add the definition of what files are needed
269 to build.
270- CMakeLists.txt, which is the compilation configuration for this module.
271
272.. Note::
273 The CMakeLists.inc is not mandatory, the user can put everything in
274 CMakeLists.txt.
275
Boris Deleticfb231172020-08-06 22:46:53 +0100276The current CMake configuration should also be updated, by updating
277CommonConfig.cmake to include the definition of the newly introduced partition
278and adding the relevant subdirectoy in ``secure_fw/CMakeLists.txt``.
279
Edison Ai1b7e8452019-12-16 10:03:52 +0800280Please refer to the source code of TF-M for more detail.
281
282Update manifest list
283--------------------
284The ``<TF-M base folder>/tools/tfm_manifest_list.yaml`` is used to collect
285necessary information of secure partition.
286
287- ``name``: The name string of the secure partition.
288- ``short_name``: should be the same as the ``name`` in the secure partition
289 manifest file.
290- ``manifest``: the relative path of the manifest file to TF-M root.
291- ``tfm_partition_ipc``: indicate if this partition is compatible with the IPC
292 model.
293- ``conditional``: Optional. Configure control macro for this partition.
294- ``version_major``: major version the partition manifest.
295- ``version_minor``: minor version the partition manifest.
296- ``pid``: Secure Partition ID value distributed in chapter `Secure Partition
297 ID Distribution`_.
298
299Reference configuration example:
300
301.. code-block:: yaml
302
303 {
304 "name": "Example Service",
305 "short_name": "TFM_SP_EXAMPLE",
Ken Liu738a4b02020-06-04 14:52:38 +0800306 "manifest": "secure_fw/partitions/EXAMPLE/tfm_example.yaml",
Edison Ai1b7e8452019-12-16 10:03:52 +0800307 "tfm_partition_ipc": true,
Boris Deleticfb231172020-08-06 22:46:53 +0100308 "conditional": "TFM_PARTITION_EXAMPLE",
Edison Ai1b7e8452019-12-16 10:03:52 +0800309 "version_major": 0,
310 "version_minor": 1,
311 "pid": 256
312 }
313
314Generate files
315==============
316After finishing the configuration works, the user needs to generate necessary
317files from manifest by using TF-M tools.
318
319.. code-block:: bash
320
Leonardo Sandovald7f72d52020-07-28 18:02:34 -0500321 cd <base folder>
Edison Ai1b7e8452019-12-16 10:03:52 +0800322 cd trusted-firmware-m
323 python ./tools/tfm_parse_manifest_list.py
324
325Implement the RoT services
326==========================
Boris Deleticfb231172020-08-06 22:46:53 +0100327To implement RoT services, the partition needs a source file which contains the
328implementations of the services, as well as the partition entry point. The user
329can create this source file under
330``<TF-M base folder>/secure_fw/partitions/EXAMPLE/EXAMPLE.c``. The linker
331detects source files according to the pattern matching defined by the
332"linker_pattern" attribute in the ``tfm_manifest_list.yaml`` file.
333
334As an example, the RoT service with SID **ROT_A** will be implemented.
335
336Entry point function
337--------------------
338This function acts as a main() function for the partition.
339On incoming signals for service calls, the entry point function handles
340signals by calling the relevant service function.
341An example entry point is given
342
343.. code-block:: c
344
345 void example_main(void)
346 {
347 psa_signal_t signals = 0;
348
349 while (1) {
350 signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
351 if (signals & ROT_A_SIGNAL) {
352 rot_A();
353 } else {
354 /* Should not come here */
355 psa_panic();
356 }
357 }
358 }
359
360Service implementation
361----------------------
362The service is implemented by the ``rot_A()`` function, which is called upon an
363incoming signal. This implementation is up to the user, however an example
364service has been included for reference. The following example sends a message
365"Hello World" when called.
366
367.. code-block:: c
368
369 static void rot_A(void)
370 {
371 const int BUFFER_LEN = 32;
372 psa_msg_t msg;
373 psa_status_t r;
374 int i;
375 uint8_t rec_buf[BUFFER_LEN];
376 uint8_t send_buf[BUFFER_LEN] = "Hello World";
377
378 psa_get(ROT_A_SIGNAL, &msg);
379 switch (msg.type) {
380 case PSA_IPC_CONNECT:
381 if (service_in_use & ROT_A_SIGNAL) {
382 r = PSA_ERROR_CONNECTION_REFUSED;
383 } else {
384 service_in_use |= ROT_A_SIGNAL;
385 r = PSA_SUCCESS;
386 }
387 psa_reply(msg.handle, r);
388 break;
389 case PSA_IPC_CALL:
390 for (i = 0; i < PSA_MAX_IOVEC; i++) {
391 if (msg.in_size[i] != 0) {
392 psa_read(msg.handle, i, rec_buf, BUFFER_LEN);
393 }
394 if (msg.out_size[i] != 0) {
395 psa_write(msg.handle, i, send_buf, BUFFER_LEN);
396 }
397 }
398 psa_reply(msg.handle, PSA_SUCCESS);
399 break;
400 case PSA_IPC_DISCONNECT:
401 assert((service_in_use & ROT_A_SIGNAL) != 0);
402 service_in_use &= ~ROT_A_SIGNAL;
403 psa_reply(msg.handle, PSA_SUCCESS);
404 break;
405 default:
406 /* cannot get here [broken SPM] */
407 psa_panic();
408 break;
409 }
410 }
411
412Test connection
413---------------
414To test that the service has been implemented correctly, the user needs to call
415it from somewhere. One option is to create a new testsuite, such as
416``<TF-M-test base folder>/test/suites/example/non_secure/example_ns_interface_testsuite.c``.
417
418.. code-block:: c
419
420 static void tfm_example_test_1001(struct test_result_t *ret)
421 {
422 char str1[] = "str1";
423 char str2[] = "str2";
424 char str3[128], str4[128];
425 struct psa_invec invecs[2] = {{str1, sizeof(str1)},
426 {str2, sizeof(str2)}};
427 struct psa_outvec outvecs[2] = {{str3, sizeof(str3)},
428 {str4, sizeof(str4)}};
429 psa_handle_t handle;
430 psa_status_t status;
431 uint32_t version;
432
433 version = psa_version(ROT_A_SID);
434 TEST_LOG("TFM service support version is %d.\r\n", version);
435 handle = psa_connect(ROT_A_SID, ROT_A_VERSION);
436 status = psa_call(handle, PSA_IPC_CALL, invecs, 2, outvecs, 2);
437 if (status >= 0) {
438 TEST_LOG("psa_call is successful!\r\n");
439 } else {
440 TEST_FAIL("psa_call is failed!\r\n");
441 return;
442 }
443
444 TEST_LOG("outvec1 is: %s\r\n", outvecs[0].base);
445 TEST_LOG("outvec2 is: %s\r\n", outvecs[1].base);
446 psa_close(handle);
447 ret->val = TEST_PASSED;
448 }
449
450Once the test and service has been implemented, the project can be built and
451executed. The user should see the "Hello World" message in the console as
452received by the testsuite.
453
454Further Notes
455-------------
Edison Ai1b7e8452019-12-16 10:03:52 +0800456
457- In the IPC model, Use PSA FF proposed memory accessing mechanism. SPM
458 provides APIs and checking between isolation boundaries, a free accessing
459 of memory can cause program panic.
460- In the IPC model, the memory checking inside partition runtime is
461 unnecessary. SPM handles the checking while memory accessing APIs are
462 called.
463- In the IPC model, the client ID had been included in the message structure
464 and secure partition can get it when calling psa_get() function. The secure
465 partition does not need to call ``tfm_core_get_caller_client_id()`` to get
466 the caller client ID anymore.
467- In the IPC model, SPM will check the security policy and partition
468 dependence between client and service. So the service does not need to
469 validate the secure caller anymore.
470
471*********
472Reference
473*********
474
475| `PSA Firmware Framework specification`_
476
477.. _PSA Firmware Framework specification: https://pages.arm.com/psa-
478 resources-ff.html?_ga=2.156169596.61580709.1542617040-1290528876.1541647333
479
480--------------
481
Kevin Pengc6d74502020-03-04 16:55:37 +0800482*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*