Docs: Structure the Design documents
- gather documents in folders:
"booting" for secure boot related designs
"services" for Secure services and SPM
"software" for general TF-M framework design and rules
- add short document names in indexes
Signed-off-by: Anton Komlev <anton.komlev@arm.com>
Change-Id: I4efd309c186e431cf24c3259a35bfef53e2eb24c
diff --git a/docs/design_docs/services/index.rst b/docs/design_docs/services/index.rst
new file mode 100644
index 0000000..5024f88
--- /dev/null
+++ b/docs/design_docs/services/index.rst
@@ -0,0 +1,21 @@
+###############
+Secure Services
+###############
+
+.. toctree::
+ :maxdepth: 1
+
+ Secure Partition Manager <secure_partition_manager.rst>
+ Secure RTL <tfm_secure_partition_runtime_library.rst>
+ Inter-Process Communication <tfm_psa_inter_process_communication.rst>
+ Stateless Services <stateless_rot_service.rst>
+ Service Signing <tfm_uniform_secure_service_signature.rst>
+ Crypto <tfm_crypto_design.rst>
+ Initial Attestation <symmetric_initial_attest.rst>
+ Internal Storage <tfm_its_service.rst>
+ Firmware Update <tfm_fwu_service.rst>
+ PS Key Management <ps_key_management.rst>
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/ps_key_management.rst b/docs/design_docs/services/ps_key_management.rst
new file mode 100644
index 0000000..6ce540f
--- /dev/null
+++ b/docs/design_docs/services/ps_key_management.rst
@@ -0,0 +1,128 @@
+========================================
+Protected Storage service key management
+========================================
+
+:Author: Jamie Fox
+:Organization: Arm Limited
+:Contact: Jamie Fox <jamie.fox@arm.com>
+
+Background
+==========
+The PSA Protected Storage API requires confidentiality for external storage to
+be provided by:
+
+ **cryptographic ciphers using device-bound keys**, a tamper resistant
+ enclosure, or an inaccessible deployment location, depending on the threat
+ model of the deployed system.
+
+A TBSA-M-compliant device must embed a Hardware Unique Key (HUK), which provides
+the root of trust (RoT) for confidentiality in the system. It must have at least
+128 bits of entropy (and a 128 bit data size), and be accessible only to Trusted
+code or Trusted hardware that acts on behalf of Trusted code. [TBSA-M]_
+
+Design description
+==================
+Each time the system boots, PS will request that the Crypto service uses a key
+derivation function (KDF) to derive a storage key from the HUK, by referring to
+the builtin key handle for the HUK. The storage key could be kept in on-chip
+volatile memory private to the Crypto partition, or it could remain inside a
+secure element. Either way it will not be returned to PS.
+
+For each call to the PSA Protected Storage APIs, PS will make requests to the
+Crypto service to perform AEAD encryption and/or decryption operations using the
+storage key (providing a fresh nonce for each encryption).
+
+At no point will PS access the key material itself, only referring to the HUK
+and storage key by their handles in the Crypto service.
+
+Key derivation
+==============
+PS will make key derivation requests to the Crypto service with calls to the
+PSA Crypto APIs. In order to derive the storage key, the following calls are
+required:
+
+.. code-block:: c
+
+ status = psa_key_derivation_setup(&op, PSA_ALG_HKDF(PSA_ALG_SHA_256));
+
+ /* Set up a key derivation operation with HUK */
+ status = psa_key_derivation_input_key(&op, PSA_KEY_DERIVATION_INPUT_SECRET,
+ TFM_BUILTIN_KEY_ID_HUK);
+
+ /* Supply the PS key label as an input to the key derivation */
+ status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_INFO,
+ key_label,
+ key_label_len);
+
+ /* Create the storage key from the key derivation operation */
+ status = psa_key_derivation_output_key(&attributes, &op, &ps_key);
+
+.. note::
+ ``TFM_BUILTIN_KEY_ID_HUK`` is a static key ID that is used to identify the
+ HUK. It has an arbitrary value defined in ``tfm_crypto_defs.h``
+
+ ``ps_key`` is a PSA Crypto key handle to a volatile key, set by the
+ derivation operation. After the call to ``psa_key_derivation_output_key``,
+ it can be used to refer the storage key.
+
+ ``key_label`` can be any string that is independent of the input key
+ material and different to the label used in any other derivation from the
+ same input key. It prevents two different contexts from deriving the same
+ output key from the same input key.
+
+The key derivation function used by the crypto service to derive the storage key
+will be HKDF, with SHA-256 as the underlying hash function. HKDF is suitable
+because:
+
+- It is simple and efficient, requiring only two HMAC operations when the length
+ of the output key material is less than or equal to the hash length (as is the
+ case here).
+- The trade-off is that HKDF is only suitable when the input key material has at
+ least as much entropy as required for the output key material. But this is the
+ case here, as the HUK has 128 bits of entropy, the same as required by PS.
+- HKDF is standardised in RFC 5869 [RFC5869]_ and its security has been formally
+ analysed. [HKDF]_
+- It is supported by the TF-M Crypto service.
+
+The choice of underlying hash function is fairly straightforward: it needs to be
+a modern standardised algorithm, considered to be secure and supported by TF-M
+Crypto. This narrows it down to just the SHA-2 family. Of the hash functions in
+the family, SHA-256 is the simplest and provides more than enough output length.
+
+Keeping the storage key private to PS
+-------------------------------------
+
+The Crypto service derives a platform key from the HUK, using the partition ID
+as the input to that derivation, and that platform key is used for the key
+derivation by PS. This happens transparently, and to PS is indistinguishable
+from deriving from the HUK except that other partitions cannot derive the
+storage key even if they know the derivation parameters.
+
+Key use
+=======
+To encrypt and decrypt data, PS will call the PSA Crypto AEAD APIs in the same
+way as the current implementation, but ``ps_key`` will refer to the storage key,
+rather than the imported HUK. For each encryption operation, the following call
+is made (and analogously for decryption):
+
+.. code-block:: c
+
+ psa_aead_encrypt(ps_key, PS_CRYPTO_ALG,
+ crypto->ref.iv, PS_IV_LEN_BYTES,
+ add, add_len,
+ in, in_len,
+ out, out_size, out_len);
+
+References
+==========
+.. [TBSA-M] Arm Platform Security Architecture Trusted Base System Architecture
+ for Armv6-M, Armv7-M and Armv8-M, version 1.0
+.. [HKDF] Hugo Krawczyk. 2010. Cryptographic extraction and key derivation: the
+ HKDF scheme. In Proceedings of the 30th annual conference on Advances in
+ cryptology (CRYPTO'10)
+.. [RFC5869] IETF RFC 5869: HMAC-based Extract-and-Expand Key Derivation
+ Function (HKDF)
+
+--------------
+
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/secure_partition_manager.rst b/docs/design_docs/services/secure_partition_manager.rst
new file mode 100644
index 0000000..366619a
--- /dev/null
+++ b/docs/design_docs/services/secure_partition_manager.rst
@@ -0,0 +1,811 @@
+########################
+Secure Partition Manager
+########################
+This document describes the Secure Partition Manager(`SPM`) implementation
+design in Trusted Firmware-M (`TF-M`).
+
+.. note::
+ - The FF-M in this document refers to the accumulated result of two
+ specifications:
+ `FF-M v1.1 Update <https://developer.arm.com/documentation/aes0039/latest>`_
+ on
+ `FF-M v1.0 <https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&la=en&hash=BE8C59DBC98212591E1F935C2312D497011CD8C7>`_.
+ - The words marked as `interpreted` are defined terms. Find the terms in
+ referenced documents if it is not described in this document.
+
+************
+Introduction
+************
+The service access process of FF-M:
+
+.. figure:: /design_docs/media/tfmdev.*
+ :align: center
+ :name: fig-tfmdev
+ :width: 80%
+
+ FF-M service access process
+
+Secure services (aka `Service`) is the component providing secure
+functionalities in `SPE`, and `Client` is the user of the `Service`. A service
+act as a client when it is accessing its depending services.
+
+Services are grouped into `Secure Partition` (aka `partition`). A partition:
+
+- Contains services with the same purpose.
+- Provides implementation required isolation boundaries.
+- Is a software development unit.
+
+Each service exposes its `Service ID` (`SID`) and `Handle` for client access
+usage. Clients access services by `SID` or `Handle` through FF-M `Client API`.
+Partitions use FF-M `Secure Partition API` when it needs to operate on client
+data or reply to a client.
+
+`SPM` is the centre of an FF-M compliant implementation, which set up and
+maintains a firmware framework that:
+
+- Implements `Client API` and `Secure Partition API`.
+- Manages partition runtime to follow FF-M.
+- Involves necessary implementation-defined items to support the
+ implementation.
+
+SPM interfaces are consist of these two categories:
+
+- FF-M defined API.
+- Extended API to support the implementation.
+
+Both API categories are compliant with FF-M concepts and guidelines. The core
+concept of TF-M SPM surrounds the FF-M defined service management and access
+process. Besides this, another important implementation part is partition
+runtime management.
+
+Partition runtime model
+=======================
+One partition must work under as `ONE` of the runtime models:
+`Inter-process communication` (`IPC`) model or `Secure Function` (`SFN`)
+model.
+
+A partition that runs under the `IPC` model looks like a classic `process`.
+There is `ONE` thread inside the partition keeps waiting for signals. SPM
+converts the service accessing info from the `Client API` call into messages
+and assert a signal to the partition. The partition calls corresponded service
+function indicated by the signal and its bound message, and reply service
+returned result to the client. The advantages of this model:
+
+- It provides better isolation by limiting the interfaces on data interactive.
+ Data are preferred to be processed in a local buffer.
+- It provides a mechanism for handling multiple service access. There is no
+ memory mapping mechanism in the MCU system, hence it is hard to provide
+ multiple function call contexts when serving multiple-threaded clients if
+ the service access is implemented in a function-call based mechanism. This
+ model converts multiple service accesses into messages, let the partition
+ handles the service access in messages one by one.
+
+The `Secure Function` (`SFN`) model partition is close to a `library`. Each
+service is provided as a function entry inside the partition. SPM launches
+the target service function after the service is found. The whole procedure
+(from client to service function) is a function call. This model:
+
+- Saves the workloads spent on `IPC` scheduling.
+
+Meanwhile, it relaxes the data interactive mechanism, for example, allow
+direct memory access (MMIOVEC). And it is hard to enable multiple-threaded
+clients service access because of multiple call context-maintenance
+difficulties.
+
+An implementation contains only `SFN` partitions fits better in the
+resource-constrained devices, it is called an `SFN model implementation`. And
+it is an `IPC model implementation` when `IPC` partitions exist in the system.
+
+.. note::
+ `IPC model implementation` can handle access to the services in the `SFN`
+ partition.
+
+Components and isolation levels
+===============================
+There are `THREE` isolation levels defined in `FF-M`. These levels can
+fulfil different security requirements by defining different isolation
+boundaries.
+
+.. figure:: /design_docs/media/modelisolation.*
+ :align: center
+ :name: fig-modelisolation
+ :width: 80%
+
+ Components and isolation boundaries
+
+.. note::
+ Concept `ARoT`, `PRoT`, `domain`, and boundaries are in the `FF-M`
+ specification.
+
+Not like an `SPE` client that can call `Client API` to access the secure
+services in one step, an `NSPE` client needs to cross the secure boundaries
+first before calling `Client API`. The component `NS Agent` in
+:numref:`fig-modelisolation` represents `NSPE` clients after they crossed
+the secure boundaries. This could help `SPM` handles the request in a
+unified way instead of care about the special boundaries.
+
+.. note::
+ `NS Agent` is a necessary implementation-defined component out of FF-M
+ specification. `NS Agent` has a dedicated stack because secure and
+ non-secure can not share the stack. It also has dedicated execution bodies.
+ For example, RPC-based `NS Agent` has a while loop that keeps waiting for
+ messages; and Trustzone-based `NS Agent` has veneer code to take over `NSPE`
+ secure call. This makes `NS Agent` is a component more like a `process`.
+ Hence in the simplest implementation (`SFN model implementation` mentioned
+ above), `NS Agent` is the only process in the system, the scheduling
+ logic can be extremely simplified since no other process execution needs to
+ be scheduled. But the scheduling interface is still necessary to SPM, this
+ could help SPM treat both `SFN` and `IPC` model implementation in a unified
+ way.
+
+ Check `NS Agent`_ for details.
+
+Implementation principle
+========================
+The principles for TF-M SPM implementation:
+
+.. important::
+ - SPM can treat these components as the client: NS Agent, SFN Partition,
+ and IPC partition.
+ - These components can provide services: SFN Partition, IPC partition, and
+ built-in services. A built-in service is built up with SPM together.
+ - All partition services must be accessed by `Client API`.
+ - Partitions interact with client data by `Secure Partition API`.
+ - Built-in services are strongly recommended to be accessed by `Client API`.
+ Customized interfaces are restricted.
+ - Built-in services can call SPM internal interfaces directly.
+
+******************
+Runtime management
+******************
+The runtime execution runs among the components, there are **4** runtime
+states:
+
+- `Initializing` state, to set up the SPM runtime environment after system
+ powers up
+- `IDLE` state, when SPM runtime environment is set up and partitions are
+ ready for service access.
+- `Serving` state, when partition is under initializing or service access
+ handling.
+- `Background` state, such as the arrival of secure interrupt or unexpected
+ faults. `Background` state returns to the state it preempts. `Background`
+ state can be nested.
+
+The state transition diagram:
+
+.. figure:: /design_docs/media/spestate.*
+ :align: center
+ :name: fig-spestate
+ :width: 70%
+
+ SPE runtime execution states
+
+Initializing
+============
+The goal of TF-M initializing is to perform necessary initialization and
+move to the `Serving`_ state. This state starts with platform-specific power
+on sequence, then `SPM` takes over the execution to perform these operations:
+
+#. A preparation initialization process before SPM runtime initialization.
+#. SPM runtime initialization.
+#. A post initialization happens after the SPM runtime initialization and
+ before the first partition gets launched.
+
+.. note::
+ These procedures and their sub-routines are recommended to be applied with
+ execution measurement mechansim to mitigate the `Hardware Fault Injection`
+ attack.
+
+Preparation initialization
+--------------------------
+The purpose of this preparation initialization is to provide a chance for
+performing those security required but generic platform power-on skipped
+operations, such as:
+
+- Restrict `SPM` execution, for example, set up memory overflow settings for
+ SPM runtime memory, or set code out of SPM as un-executable, even though
+ SPM is a privileged component in general.
+
+.. note::
+ The ``logging``-related peripheral can be set up **AT THIS STEP**, if
+ logging is enabled and it needs peripheral support. There is no standalone
+ initializing HAL API proposed for logging, so here is an ideal place for
+ initializing them.
+
+This procedure is abstracted into one `HAL`, and a few example procedures
+are implemented as its sub-routines for reference:
+
+- Architecture extensions initialization, Check chapter
+ `Architecture security settings`_ for detailed information.
+- Isolation and lifecycle initialization.
+
+The load isolation boundaries need to be set up here, such as SPE/NSPE
+boundary, and ARoT/PRoT boundary if isolation level 2 is applied.
+
+The lifecycle is initiated by a secure bootloader usually. And in this stage
+of SPM initializing, SPM double-checks the lifecycle set up status (following
+a specific lifecycle management guidelines). Note that the hardware debugger
+setting can be part of lifecycle settings.
+
+.. important::
+ Double-check debugger setting when performing a product release.
+
+SPM runtime initialization
+--------------------------
+This procedure initializes necessary runtime operations such as memory
+allocator, loading partitions and partition-specific initialization
+(binding partitions with platform resources).
+
+The general processes:
+
+#. Initialize runtime functionalities, such as memory allocator.
+#. Load partitions by repeating below steps:
+
+ * Find a partition load information.
+ * Allocate runtime objects for this partition.
+ * Link the runtime objects with load information.
+ * Init partition contexts (Thread and call context).
+ * Init partition isolation boundaries (MMIO e.g.).
+ * Init partition interrupts.
+
+After no more partitions to be loaded, the SPM runtime is set up but
+partitions' initialization routines have not run yet - the partition runtime
+context is initialized for the routine call.
+
+The partition initialization routine is a special service that serves SPM
+only, because:
+
+- SPM needs to call the initialization routine, just like it calls into
+ the service routine.
+- The partition initialization routine can access its depending services.
+ Putting initialization routine in the same runtime environment as common
+ service routines can avoid special operations.
+
+Hence a `Partition initialization client` needs to be created to initialize
+the SFN partitions, because:
+
+- `SPM runtime initialization` happen inside a special runtime environment
+ compare to the partition runtime execution, then an environment switching
+ is needed.
+- IPC partitions are initialized by the scheduler and dependencies are
+ handled by signals and messages asynchronously, hence IPC partitions can
+ process the dependencies by their own.
+
+The `Partition initialization client` is created differently based on the
+implementation runtime model:
+
+- A SFN client is created under the SFN model implementation.
+- A IPC client is created under the IPC model implementation. This client
+ thread has the highest priority.
+
+As the other partitions, the client is created with context standby, and it
+is executed after the `Post initialization`_ stage.
+
+Post initialization
+-------------------
+Platform code can change specific partition settings in this procedure before
+partitions start. A few SPM API is callable at this stage, such as set a
+signal into a specific partition, or customized peripheral settings.
+
+Serving
+=======
+Two execution categories work under this state:
+
+- `Partition initialization routine execution`_.
+- `Secure service access`_.
+
+This state indicates the serving is ongoing. It is mainly the service routine
+execution, plus a few SPM executions when SPM API gets called.
+
+.. important::
+ The service access process introduce in this chapter
+ (Such as `Secure service access`_) is abstracted from the FF-M
+ specification. Reference the FF-M specification for the details of each
+ step.
+
+Partition initialization routine execution
+------------------------------------------
+The partition initialization routines get called. One partition may access its
+depending services during initializing, then this procedure is a
+`Secure service access`_.
+
+The initialization routine gets called initially by
+`Partition initialization client`, also can be called by Client API before
+service access, if the target partition is not initialized but a service
+access request is raised by one client.
+
+Secure service access
+---------------------
+The process of service access:
+
+#. A `client` calls an FF-M Client API.
+#. `SPM` validates inputs and looks up for the targeted service.
+#. `SPM` constructs the request to be delivered under a proper runtime
+ mechanism.
+#. The target service gets executed. It can perform internal executions or
+ access depending services to prepare the response. It also can wait for
+ specific signals.
+#. The target service calls FF-M Secure Partition API to request a reply to
+ the client.
+#. SPM delivers the response to the client, and the API called by the client
+ returns.
+
+The mechanism of how SPM interact with the target partition depends on the
+partition runtime model.
+
+- Access to a service in an SFN partition is a function call, which does not
+ switch the current process indicator.
+- Access to a service in an IPC partition leads to scheduling, which switches
+ the current process indicator.
+- When the execution roams between components because of a function call or
+ scheduling, the isolation boundaries NEED to be switched if there are
+ boundaries between components.
+
+.. figure:: /design_docs/media/hybridruntime.*
+ :align: center
+ :name: fig-hybridruntime
+ :width: 60%
+
+No matter what kind of partition a client is trying to access, the SPM API is
+called firstly as it is the interface for service access. There are two ABI
+types when calling SPM API: Cross-boundary or No-cross-boundary.
+
+Calling SPM API
+---------------
+SPM is placed in the PRoT domain. It MAY have isolation boundaries under
+particular isolation levels. For example:
+
+- There are boundaries between ARoT components and SPM under isolated level 2
+ and 3.
+
+Then API SPM provided needs to support the function call (no boundary
+switching) and cross-boundary call. A direct call reaches the API entrance
+directly, while a cross-boundary call needs a mechanism (Supervisor call e.g.)
+to cross the boundary first before reaching the API entrance.
+
+.. figure:: /design_docs/media/twocalltypes.*
+ :align: center
+ :name: fig-twocalltypes
+ :width: 60%
+
+ SPM call types
+
+SPM internal execution flow
+---------------------------
+SPM internal execution flow as shown in diagram:
+
+.. figure:: /design_docs/media/abi_scheduler.*
+ :align: center
+ :name: fig-abi_scheduler
+ :width: 60%
+
+ SPM API runtime
+
+The process:
+
+- PSA API gets called by one of the ABI mentioned in the last chapter as
+ `ABI 1` in the diagram.
+- The unified API Handler calls FF-M and backend subroutines in sequence.
+- The `FF-M` subroutine performs `FF-M` defined operations.
+- The backend operations perform target partition runtime model decided
+ operations. For example, enqueue message into the target partition under
+ the IPC runtime model, or prepare to call context with the message as the
+ parameters under the SFN runtime model.
+- API Handler triggers different ABI based on the result of the backends.
+
+The API handler:
+
+- Can process the `PROGRAMMER_ERROR` in a unified place.
+- Can see the prepared caller and callee context, with exited SPM context. It
+ is an ideal place for subsequent operations such as context switching.
+
+A example code:
+
+.. code-block:: c
+
+ void abi(void *p)
+ {
+ status = spm_api(p);
+ /*
+ * Now both the caller and calle context are
+ * managed by spm_api.
+ */
+ if (status == ACTION1) {
+ /*
+ * Check if extra operations are required
+ * instead of a direct return.
+ */
+ exit_action1();
+ }
+ }
+
+The explanation about `Scheduler Lock`:
+
+Some FF-M API runs as a generic thread to prevent long time exclusive
+execution. When a preemption happens, a new partition thread can call SPM API
+again, makes SPM API nested. It needs extra memory in SPM to be allocated to
+store the preempted context. Lock the scheduler while SPM API is executing can
+ensure SPM API complete execution after preemption is handled. There can be
+multiple ways to lock the scheduler:
+
+- Set a scheduler lock.
+- Set SPM API thread priority as the highest.
+
+Backend service messaging
+-------------------------
+A message to service is created after the target service is found and the
+target partition runtime model is known. The preparation before ABI triggers
+the final accessing:
+
+- The message is pushed into partition memory under a specific ABI mechanism
+ if the target partition model is `SFN` and there are boundaries between SPM
+ and the target partition. After this, requests a specific call type to the
+ SPM ABI module.
+- The target service routine is get called with the message parameter if
+ there are no boundaries between SPM and the target partition and the
+ partition runtime is `SFN`.
+- The message is queued into the partition message list if the target
+ partition runtime model is `IPC`.
+- IPC partition replies to the client by `psa_reply`, which is another SPM API
+ call procedure.
+- SFN partition return triggers an implied `psa_reply`, which is also another
+ SPM API call procedure.
+
+.. note::
+ The backends also handle the isolation boundary switching.
+
+Sessions and contexts
+---------------------
+FF-M API allows multiple sessions for a service if the service is classic
+connection-based. The service can maintain multiple local session data and use
+`rhande` in the message body to identify which client this session is bound
+with.
+
+But this does not mean when an ongoing service accessing is preempted,
+another service access request can get a chance for new access. This is
+because of the limited context storage - supporting multiple contexts in a
+common service costs much memory, and runtime operations(allocation and
+re-location). Limited the context content in the stack only can mitigate the
+effort, but this requirement requires too much for the service development.
+
+The implementation-decisions are:
+
+- IPC partitions handles messages one by one, the client get blocked before
+ the service replying to the client.
+- The client is blocked when accessing services are handling a service
+ request in an SFN partition.
+
+ABI type summary
+----------------
+The interface type is decided by the runtime model of the target component.
+Hence PSA API has two types of ABI: `Cross-boundary ABI` and
+`Function call ABI`. After SPM operations, one more component runtime type
+shows up: The IPC partition, hence `schedule` is the mechanism when accessing
+services inside an IPC partition.
+
+.. figure:: /design_docs/media/spmabitypes.*
+ :align: center
+ :name: fig-spmabi
+ :width: 60%
+
+ ABI types
+
+.. note::
+ The API that does not switch context returns directly, which is not
+ covered in the above diagram.
+
+IDLE state
+==========
+The `IDLE state` can be represented by the `NS Agent` action:
+
+- Launching NSPE software (Trustzone case, e.g.), or send a signal to NSPE
+ software (RPC case, e.g.).
+
+It is because `NS Agent` is the last component being initialized in the
+system. Its execution indicates other partitions' initialization has
+accomplished.
+
+Background state
+================
+Background execution can happen at any time when the arrival of interrupts or
+execution faults. An ongoing background execution indicates the state is a
+`Background state`. The characteristics:
+
+- The background state has a higher execution priority than other states -
+ other states stall when the background state is executing.
+- Background execution can be nested. For example, an
+ interrupt handler can preempt an ongoing interrupt execution.
+- Particular partition code can be involved in the background state, for
+ example, the `First Level Interrupt Handler (FLIH)` of one partition.
+- Background state MUST return to the state it preempts.
+
+.. note::
+ Interrupt handling is a common background state example. Check Interrupt
+ design document for details.
+
+******************************
+Practical implementation items
+******************************
+This chapter describes the practical implementation contents.
+
+.. important::
+ Arm M-profile architecture is the default hardware architecture when
+ describing architecture-specific items.
+
+The general M-profile programming is not involved in this document. The
+following chapters introduce the mandatory settings for security
+requirements.
+
+Architecture security settings
+==============================
+When an `Armv8m Security Extension` (Aka `Trustzone-M`) is available in the
+system, these settings are required to be set:
+
+- The MSPLIM needs to be set correctly to prevent stack overflow.
+- The exception handler priority needs to be decided.
+- Boost the secure handler mode priority to prevent NSPE from preempting SPE
+ handler mode execution(`AIRCR.PRIS`).
+- Disable NSPE hardware faults when a secure fault is happening. Trap in the
+ secure fault with the highest priority can be a valid option.
+- Push seals on the stack top when a stack is allocated (`TFMV-1`). Also
+ check `Stack seal`_ chapter for details.
+
+Besides `Armv8m Security Extension`, these settings need to care when
+`Floatpoint Extension` is enabled for partition usage:
+
+- `FPCCR.TS`, `FPCCR.CLRONRET` and `FPCCR.CLRONRETS` need to be set when
+ booting.
+- `CPACR.CP10` and `CPACR.CP11` need to be set when booting.
+
+.. important::
+ Floatpoint usage is prohibited in SPM and background execution.
+
+Stack seal
+----------
+When Trustzone-M is applied, the architecture specification recommends sealing
+the secure stack by:
+
+- Push two `SEAL` values (`0xFEF5EDA5`) at the stack bottom, when a stack is
+ allocated.
+- Push two `SEAL` values on the stack pointer which is going to be switched
+ out.
+
+Check architecture specification and vulnerability `TFMV-1` for details.
+
+Trustzone-M reentrant
+---------------------
+The Trustzone-M has characteristics that:
+
+- SPE keeps the last assigned stack pointer value when execution leaves SPE.
+- SPE execution can be preempted by NSPE which causes an execution left.
+
+It is possible that NSPE preemption caused a second thread calls into SPE and
+re-uses the secure stack contains the first thread's context, which obviously
+causes information leakage and runtime state inconsistent.
+
+Armv8.1-M provides the hardware setting `CCR_S.TRD` to prevent the reentrant.
+On an Armv8.0-M architecture, extra software logic needs to be added at the
+veneer entry:
+
+- Check if the local stack points to a `SEAL` when veneer code get executed.
+
+.. code-block:: c
+
+ /* This is a theoretical code that is not in a real project. */
+ veneer() {
+ content = get_sp_value();
+ if (context != SEAL) /* Error if reentrant detected */
+ error();
+ }
+
+SPM Runtime ABI
+===============
+This chapter describes the runtime implementation of SPM.
+
+Scheduling
+----------
+The scheduling logic is put inside the PendSV mode. PendSV mode's priority
+is set as one level higher than the default thread mode priority. If
+`Trustzone-M` is present, the priority is set as the lowest just above NS
+exception priority to prevent a preemption in secure exceptions.
+
+PendSV is an ideal place for scheduling logic, because:
+
+- An interrupt triggered scheduling during PendSV execution lead to another
+ PendSV execution before exception return to the thread mode, which can find
+ the latest run-able thread.
+
+Function call ABI
+-----------------
+In the diagram :numref:`fig-abi_scheduler`, the ABI can have two basic
+types: cross-boundary and direct call (No-cross-boundary).
+
+When applying `SVCall` (`SVC`) as the cross-boundary mechanism, the
+implementation can be straight like:
+
+- The SVC handler calls SPM internal routines, and eventually back to the
+ handler before an exit.
+
+Under the IPC model implementation, to re-use `ABI 2` in `No-cross-boundary`,
+a software ABI needs to be provided.
+
+While under the SFN model plus isolation level 1, both `ABI 1` and `ABI 2` can
+be a direct function call.
+
+NS Agent
+========
+The `NS Agent`(`NSA`) forwards NSPE service access request to SPM. It is a
+special `partition` that:
+
+- It does not provide FF-M aligned secure services.
+- It runs with the second-lowest priority under `IPC model implementation`
+ (The IDLE thread has the lowest priority).
+- It has isolation boundaries and an individual stacks.
+- It requires specific services and mechanisms compared to common partitions.
+
+There are two known types for NS Agent:
+
+- Trustzone-M based.
+- Remote Procedure Call (RPC) based.
+
+This process is put inside the ARoT domain, to prevent assign unnecessary
+PRoT permissions to the NSPE request parsing logic.
+
+Trustzone-M specific
+--------------------
+The functionalities of a Truszone-M specific NSA is:
+
+- Launch NSPE when booting.
+- Wait in the veneer code, and get executed when NSPE accesses services.
+
+As there may be multiple NSPE threads calling into SPE, and SPM wants to
+identify them, special mechanisms can be proposed to provide the identification.
+Check specific NS ID client ID or context related documents for details.
+
+.. figure:: /design_docs/media/tzcontext.*
+ :align: center
+ :name: fig-tzcontext
+ :width: 40%
+
+ TZ NSA and specific service
+
+RPC specific
+------------
+Compare to Trustzone-M NSA, RPC NSA looks closer to a generic partition:
+
+- It has a message loop, keep waiting for RPC events.
+- It converts received RPC events into FF-M API call to target services.
+
+And compared to generic partitions, the differences are:
+
+- It parses RPC messages to know which NSPE thread is accessing services.
+ Hence it needs special interfaces to help SPM to identify the NSPE clients.
+- It needs to check NSPE client memory and map to local before calling SPM API.
+- It cannot be blocked during API calls, which affects handling the RPC
+ requests.
+
+Partition
+=========
+A partition is a set of services in the same scope. Services are generally
+implemented as functions, and the partition exposes the services in different
+ways bases on the partition model: `IPC` or `SFN`.
+
+A partition build generates these outputs:
+
+- A partition load information, used by SPM.
+- A partition program containing service interface and logic, typically a
+ library.
+- An optional service API set for easier client usage, by encapsulating
+ the low-level `FF-M` Client API. These API needs to be integrated
+ into client space.
+
+Partition loading
+-----------------
+SPM needs to set up runtime objects to manage partitions by parsing the load
+information of partitions. In general, the partition load information is
+stored in a const memory are can be random read directly, hence SPM can direct
+link runtime objects to the load information without a copy operation. This
+is called a `Static Load` mechanism.
+
+Each partition has different numbers of dependencies and services, this makes
+the load information size of each partition is different, it would be hard
+to put such variable size elements in an array. The solution here is putting
+these elements in a dedicated section, for SPM enumerating while loading.
+Each partition can define variable size load information type bases on the
+common load info type.
+
+The common load information:
+
+.. code-block:: c
+
+ struct partition_load_info_t {
+ uint32_t psa_ff_ver; /* Encode the version with magic */
+ int32_t pid; /* Partition ID */
+ uint32_t flags; /* ARoT/PRoT, SFN/IPC, priority */
+ uintptr_t entry; /* Entry point */
+ size_t stack_size; /* Stack size */
+ size_t heap_size; /* Heap size */
+ uint32_t ndeps; /* Dependency number */
+ uint32_t nservices; /* Service number */
+ uint32_t nassets; /* Asset numbers */
+ uint32_t nirqs; /* Number of IRQ owned by Partition */
+ };
+
+ And the example for a specific partition load info:
+ struct partition_example_load_info_t {
+ struct partition_load_info_t ldi; /* Common info info */
+ uint32_t deps[10]; /* Dependencies */
+ /* ... other infos ... */
+ };
+
+Peripheral binding
+------------------
+A partition can declare multiple peripherals (Interrupts are part of
+peripherals). The peripherals binding process:
+
+- The tooling references symbols in a fixed pattern in the partition load
+ information.
+- The HAL implementation needs to provide the symbols being referenced.
+- SPM calls HAL API to bind the partition info with devices When the partition
+ gets loading.
+- The platform HAL acknowledges the binding if validation pass on SPM given
+ load information.
+
+***************************
+Integration and development
+***************************
+These modules are expected to be object/library level modularised, each
+module should be generated into object/library at build time:
+
+.. list-table:: Object level modularization
+ :header-rows: 1
+ :widths: 40 60
+
+ * - Name
+ - Description
+ * - SPM
+ - All SPM related modules such as SPM, system, and so on.
+ * - Platform
+ - Platform sources are switchable.
+ * - Services and Secure Partition
+ - These items should be standalone.
+ * - Service Runtime Library
+ - This is a shared runtime library.
+
+HAL
+===
+The HAL here mainly refers to the SPM HAL. The SPM HAL implementation is
+running with the same privilege level and hardware mode with SPM. The
+implementation is object level modularized with SPM.
+
+Check the `HAL` design document for details.
+
+Configurations
+==============
+The same TF-M code base is flexible to address different implementation
+requirements, from the simplest device with isolation level 1 to the most
+complicated device with isolation level 3 and optional isolation rules.
+
+These configurations are set by switches, during the build time, as runtime
+support costs extra resources. The common configurations are named `profile`.
+There are several profiles defined.
+
+*******
+History
+*******
+
+.. list-table:: Revision
+ :header-rows: 1
+ :widths: 20 80
+
+ * - Date
+ - Description
+ * - 2021 Apr-Sep
+ - Updated to cover the implementation for `FF-M v1.1` features.
+ * - 2018
+ - Created as 'TF-M Inter-Process Communication' which is deprecated as
+ this document covers whole SPM content.
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/stateless_rot_service.rst b/docs/design_docs/services/stateless_rot_service.rst
new file mode 100644
index 0000000..964c18c
--- /dev/null
+++ b/docs/design_docs/services/stateless_rot_service.rst
@@ -0,0 +1,228 @@
+##########################################
+Stateless Root of Trust Services Reference
+##########################################
+
+:Author: Mingyang Sun
+:Organization: Arm Limited
+:Contact: mingyang.sun@arm.com
+
+
+************
+Introduction
+************
+
+This document describes the implementation for the FF-M v1.1 feature -
+'Stateless RoT Service', and the related references when developing RoT
+services.
+
+It is recommended to refer to the FF-M v1.0 specification [1]_ and FF-M v1.1
+extension [2]_ for background and rationale details.
+
+
+**********************
+Implementation Details
+**********************
+
+This chapter describes the implementation-defined items, including stateless
+handle value definition, tooling update, and programming API changes.
+
+Stateless Handle Value Definition
+=================================
+
+The index, stateless indicator, and service version information are encoded into
+a handle by the manifest tooling, and then generated to header file ``sid.h``.
+
+.. list-table:: Bit Fields of Stateless Handle
+ :header-rows: 1
+ :widths: 20 80
+
+ * - Bits
+ - Field Description
+ * - bit 31
+ - reserved
+ * - bit 30
+ - stateless handle indicator bit, always 1
+ * - bit 29 - bit 16
+ - reserved
+ * - bit 15 - bit 8
+ - service version requested by client - for client version check
+ * - bit 7 - bit 0
+ - the handle index, [0, 31]
+
+Since connection-based services and stateless services share the same PSA API
+``psa_call()``, an indicator bit is set in the handle indicate the type of the
+handle. If it is set, the handle is stateless, and definition is as described
+in the table above. Maximum connection-based handle is 0x3FFFFFFF, thus the
+indicator bit is always 0.
+
+The index is used for organizing stateless services in manifest tool and
+locating a stateless service in SPM logic. A range of index [0, 31] is the
+initial implementation. Future expansion is possible.
+
+Tooling Support
+===============
+
+TF-M provides a tool (``tools/tfm_parse_manifest_list.py``) to generate source
+header files required by partition and services. For example, the generated
+``sid.h`` contains service ID and version. The tooling is extended to generate
+stateless handle from partition manifests automatically.
+
+The ``stateless_handle`` attribute in manifest is only supported by partitions
+with firmware framework version 1.1.
+
+- If ``stateless_handle`` in manifest is set to an integer, the index is
+ ``stateless_handle - 1``.
+- If it is ``auto`` or not set, the first empty index in range [0, 31] is
+ assigned.
+- Other settings - tooling reports an error.
+
+Finally, the tooling encodes the handle according to definitions in
+`Stateless Handle Value Definition`_ section, and writes them to ``sid.h``
+header file.
+
+Changes in Programming API
+==========================
+
+This chapter describes the changes in programming API for stateless services.
+The following APIs' bebavious and message data structure members are updated to
+support the stateless service.
+
+psa_connect()
+-------------
+
+According to FF-M v1.1, client calling ``psa_connect()`` with the SID of a
+stateless RoT Service is a ``PROGRAMMER_ERROR``.
+
+psa_close()
+-----------
+
+According to FF-M v1.1, client passing a stateless handle to call this API is a
+``PROGRAMMER_ERROR``.
+
+psa_call()
+----------
+
+.. code-block:: c
+
+ psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len)
+
+API parameters and behaviour change:
+
+1. The ``handle`` parameter must be a stateless handle defined in
+ ``psa_manifest/sid.h`` when requesting a stateless service.
+2. This API validates stateless handle, decodes index and service version
+ information from it. SPM uses the index to know which stateless service is
+ requested.
+3. This API performs some operations as ``psa_connect()`` does, such as the
+ authorization check, service and client version check, and handle space
+ allocation.
+
+Service behaviour change during a "psa_call":
+
+Service does not accept connection and disconnection messages. After a
+"psa_call" request is serviced, it calls ``psa_reply()``, frees the connection
+handle to handle pool.
+
+psa_set_rhandle()
+-----------------
+
+According to FF-M v1.1, stateless service calling this API on a message is a
+``PROGRAMMER_ERROR`` and it will never return.
+
+psa_msg_t type
+--------------
+
+The ``rhandle`` member of a ``psa_msg_t`` type received by a stateless RoT
+Service is always ``NULL``.
+
+
+**************************
+Application Recommendation
+**************************
+
+There are particular services that do not need sessions. The access to the
+service is a one-shot connection. These services provide standalone operations
+that do not require any non-volatile state of resources to be maintained by the
+RoT service itself or do not expose any kind of context or session to the
+caller. Such services are recommended to be implemented as stateless, to provide
+quick access and to avoid extra overheads.
+
+In this case, ``rhandle`` access would be prohibited as it is used for saving
+state or non-volatile resources while stateless services do not need them.
+
+Update Feasibility of Existing Services
+=======================================
+
+TF-M native services are used widely. They only need standalone operations and
+do not need to keep state between sessions. For example, the service in Crypto
+partition does not do anything during ``psa_connect()`` or ``psa_close()``
+process. Same for services in other partitions, thus all of them can be
+implemented as stateless.
+
+Analysis for them:
+
+.. list-table:: TF-M Partition Services Update Possibility
+ :header-rows: 1
+ :widths: 30 30 40
+
+ * - Partition
+ - Number of Services
+ - Can be Stateless
+ * - ITS
+ - 4
+ - All
+ * - PS
+ - 5
+ - All
+ * - Crypto
+ - 1
+ - All
+ * - FWU
+ - 6
+ - All
+ * - Platform
+ - 4
+ - All
+ * - Initial Attestation
+ - 2
+ - All
+
+Other services are not analyzed here.
+
+Grouping Services
+=================
+
+Stateless service table is stored statically, and TF-M supports 32 stateless
+services currently.
+
+Similar stateless services in a partition could be grouped, and assign one
+``SID`` for the group. The ``type`` parameter in ``psa_call()`` could be
+extended to identify the service in group. In this case, it is recommended to
+use consecutive value for ``type``.
+
+It is recommended that each Seccure Partition declares one stateless service
+and uses the type parameter to distinguish different stateless services.
+Therefore, more stateless services can be supported.
+
+Migrating to Stateless Services
+===============================
+
+Please refer to Chapter 4 "Stateless Root of Trust services", Appendix B.3.2
+"Using a stateless RoT Service", and Appendix D "Implementing session-less RoT
+Services" in FF-M v1.1 document for details on which kind of service can be
+stateless and how to implement a stateless service.
+
+
+*********
+Reference
+*********
+
+.. [1] `FF-M v1.0 Specification <https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4>`__
+
+.. [2] `FF-M v1.1 Extention <https://documentation-service.arm.com/static/600067c09b9c2d1bb22cd1c5?token=>`__
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/symmetric_initial_attest.rst b/docs/design_docs/services/symmetric_initial_attest.rst
new file mode 100644
index 0000000..bc20284
--- /dev/null
+++ b/docs/design_docs/services/symmetric_initial_attest.rst
@@ -0,0 +1,564 @@
+#################################################
+Symmetric key algorithm based Initial Attestation
+#################################################
+
+:Author: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+
+************
+Introduction
+************
+
+This document proposes a design of symmetric key algorithm based Initial
+Attestation in TF-M.
+
+Symmetric key algorithm based Initial Attestation
+(*symmetric Initial Attestation* for short) signs and verifies Initial
+Attestation Token (IAT) with a symmetric cryptography signature scheme, such as
+HMAC.
+It can reduce TF-M binary size and memory footprint on ultra-constrained devices
+without integrating asymmetric ciphers.
+
+This proposal follows PSA Attestation API document [1]_.
+
+.. note ::
+
+ As pointed out by PSA Attestation API [1]_, the use cases of Initial
+ Attestation based on symmetric key algorithms can be limited due to
+ the associated infrastructure costs for key management and operational
+ complexities. It may also restrict the ability to interoperate with
+ scenarios that involve third parties.
+
+***************
+Design overview
+***************
+
+The symmetric Initial Attestation follows the existing IAT generation sequence
+for Initial Attestation based on asymmetric key algorithm
+(*asymmetric Initial Attestation* for short).
+
+As Profile Small design [2]_ requests, a configuration flag
+``SYMMETRIC_INITIAL_ATTESTATION`` selects symmetric initial attestation during
+build.
+
+The top-level design is shown in :ref:`overall-diagram-figure` below.
+
+.. _overall-diagram-figure:
+
+.. figure:: /design_docs/media/symmetric_initial_attest/overall_diagram.png
+ :align: center
+
+ Overall design diagram
+
+Symmetric Initial Attestation adds its own implementations of some steps in IAT
+generation in Initial Attestation secure service. More details are covered in
+`IAT generation in Initial Attestation secure service`_.
+
+The interfaces and procedures of Initial Attestation secure service are not
+affected. Refer to Initial Attestation Service Integration Guide [3]_ for
+details of the implementation of Initial Attestation secure service.
+
+Symmetric Initial Attestation invokes ``t_cose`` library to build up
+``COSE_Mac0`` structure.
+``COSE_Mac0`` support is added to ``t_cose`` library in TF-M since official
+``t_cose`` hasn't supported ``COSE_Mac0`` yet. The design of ``COSE_Mac0``
+support is covered in `COSE_Mac0 support in t_cose`_.
+
+.. note ::
+
+ The ``COSE_Mac0`` implementation in this proposal is a prototype only for
+ Proof of Concept so far. It may be replaced after ``t_cose`` officially
+ supports ``COSE_Mac0`` message.
+
+Several HAL APIs are defined to fetch platform specific assets required by
+Symmetric Initial Attestation. For example, ``tfm_plat_get_symmetric_iak()``
+fetches symmetric Initial Attestation Key (IAK). Those HAL APIs are summarized
+in `HAL APIs`_.
+
+Decoding and verification of symmetric Initial Attestation is also included in
+this proposal for regression test.
+The test suites and IAT decoding are discussed in `TF-M Test suite`_.
+
+``QCBOR`` library and Crypto service are also invoked. But this proposal doesn't
+require any modification to either ``QCBOR`` or Crypto service. Therefore,
+descriptions of ``QCBOR`` and Crypto service are skipped in this document.
+
+****************************************************
+IAT generation in Initial Attestation secure service
+****************************************************
+
+The sequence of IAT generation of symmetric Initial Attestation is shown in
+:ref:`ia-service-figure` below. Note that the ``Register symmetric IAK`` stage
+is no longer required due to changes in the Crypto partition
+(``attest_symmetric_key.c`` is now responsible only for calculating the instance
+ID).
+
+.. _ia-service-figure:
+
+.. figure:: /design_docs/media/symmetric_initial_attest/ia_service_flow.png
+ :align: center
+
+ Symmetric IAT generation flow in Initial Attestation secure service
+
+In Initial Attestation secure service, symmetric Initial Attestation implements
+the following steps in ``attest_create_token()``, which are different from those
+of asymmetric Initial Attestation.
+
+ - ``attest_token_start()``
+ - Instance ID claims
+ - ``attest_token_finish()``
+
+If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected, symmetric Initial Attestation
+dedicated implementations of those steps are included in build.
+Otherwise, asymmetric Initial Attestation dedicated implementations are included
+instead.
+
+Symmetric Initial Attestation implementation resides a new file
+``attest_symmetric_key.c`` to handle symmetric Instance ID related operations.
+Symmetric Initial Attestation dedicated ``attest_token_start()`` and
+``attest_token_finish()`` are added in ``attestation_token.c``.
+
+The details are covered in following sections.
+
+Symmetric Instance ID
+=====================
+
+Symmetric Initial Attestation dedicated ``attest_symmetric_key.c`` implements
+the ``attest_get_instance_id()`` function. This function returns the Instance ID
+value, calculating it if it has not already been calculated. Refer to
+`Instance ID claim_` for more details.
+
+.. note ::
+
+ Only symmetric IAK for HMAC algorithm is allowed so far.
+
+Instance ID calculation
+-----------------------
+
+In symmetric Initial Attestation, Instance ID is also calculated the first time
+it is requested. It can protect critical symmetric IAK from being frequently
+fetched, which increases the risk of asset disclosure.
+
+The Instance ID value is the output of hashing symmetric IAK raw data *twice*,
+as requested in PSA Attestation API [1]_. HMAC-SHA256 may be hard-coded as the
+hash algorithm of Instance ID calculation.
+
+.. note ::
+
+ According to RFC2104 [4]_, if a HMAC key is longer than the HMAC block size,
+ the key will be first hashed. The hash output is used as the key in HMAC
+ computation.
+
+ In current design, HMAC is used to calculate the authentication tag of
+ ``COSE_Mac0``. Assume that symmetric IAK is longer than HMAC block size
+ (HMAC-SHA256 by default), the Instance ID is actually the HMAC key for
+ ``COSE_Mac0`` authentication tag generation, if Instance ID value is the
+ output of hashing IAK only *once*.
+ Therefore, attackers may request an valid IAT from device and fake malicious
+ ones by using Instance ID to calculate valid authentication tags, to cheat
+ others.
+
+ As a result, symmetric IAK raw data should be hashed *twice* to generate the
+ Instance ID value.
+
+The Instance ID calculation result is stored in a static buffer.
+Token generation process can call ``attest_get_instance_id()`` to
+fetch the data from that static buffer.
+
+attest_token_start()
+====================
+
+Symmetric Initial Attestation dedicated ``attest_token_start()`` initializes the
+``COSE_Mac0`` signing context and builds up the ``COSE_Mac0`` Header.
+
+The workflow inside ``attest_token_start()`` is shown in
+:ref:`attest-token-start-figure` below.
+
+.. _attest-token-start-figure:
+
+.. figure:: /design_docs/media/symmetric_initial_attest/attest_token_start.png
+ :align: center
+
+ Workflow in symmetric Initial Attestation ``attest_token_start()``
+
+Descriptions of each step are listed below:
+
+#. ``t_cose_mac0_sign_init()`` is invoked to initialize ``COSE_Mac0`` signing
+ context in ``t_cose``.
+
+#. The symmetric IAK handle is set into ``COSE_Mac0`` signing context via
+ ``t_cose_mac0_set_signing_key()``.
+
+#. Initialize ``QCBOR`` encoder.
+
+#. The header parameters are encoded into ``COSE_Mac0`` structure in
+ ``t_cose_mac0_encode_parameters()``.
+
+#. ``QCBOREncode_OpenMap()`` prepares for encoding the ``COSE_Mac0`` payload,
+ which is filled with IAT claims.
+
+All the ``COSE_Mac0`` functionalities in ``t_cose`` are covered in
+`COSE_Mac0 support in t_cose`_.
+
+Instance ID claim
+=================
+
+Symmetric Initial Attestation also implements Instance ID claims in
+``attest_add_instance_id_claim()``.
+
+The Instance ID value is fetched via ``attest_get_instance_id()``.
+The value has already been calculated during symmetric IAK registration. See
+`Instance ID calculation`_ for details.
+
+The other steps are the same as those in asymmetric Initial Attestation
+implementation. The UEID type byte is set to 0x01.
+
+attest_token_finish()
+=====================
+
+Symmetric Initial Attestation dedicated ``attest_token_finish()`` calls
+``t_cose_mac0_encode_tag()`` to calculate and encode the authentication tag of
+``COSE_Mac0`` structure.
+
+The whole COSE and CBOR encoding are completed in ``attest_token_finish()``.
+
+The simplified flow in ``attest_token_finish()`` is shown in
+:ref:`attest-token-finish-figure` below.
+
+.. _attest-token-finish-figure:
+
+.. figure:: /design_docs/media/symmetric_initial_attest/attest_token_finish.png
+ :align: center
+
+ Workflow in symmetric Initial Attestation ``attest_token_finish()``
+
+***************************
+COSE_Mac0 support in t_cose
+***************************
+
+``COSE_Mac0`` supports in ``t_cose`` in TF-M include the following major
+functionalities:
+
+ - Encoding ``COSE_Mac0`` structure
+ - Decoding and verifying ``COSE_Mac0`` structure
+ - HMAC computation to generate and verify authentication tag
+ - Short-circuit tagging for test mode
+
+According to RFC8152 [5]_, ``COSE_Mac0`` and ``COSE_Sign1`` have similar
+structures. Therefore, the prototype follows ``COSE_Sign1`` implementation to
+build up ``COSE_Mac0`` file structure and implement ``COSE_Mac0`` encoding and
+decoding.
+
+Although ``COSE_Mac0`` can share lots of data types, APIs and encoding/decoding
+steps with ``COSE_Sign1`` in implementation, this prototype separates
+``COSE_Mac0`` implementation from ``COSE_Sign1``. ``COSE_Mac0`` owns its
+dedicated signing/verification contexts, APIs and encoding/decoding process.
+The purposes of separating ``COSE_Mac0`` and ``COSE_Sign1`` are listed below
+
+- It can keep changes to ``COSE_Sign1`` as small as possible and avoid conflicts
+ with development in ``COSE_Sign1```. It can decrease conflicts if ``t_cose``
+ in TF-M is synchronized with original ``t_cose`` repository later.
+- ``COSE_Mac0`` and ``COSE_Sign1`` are exclusive in TF-M use cases.
+ It cannot decrease TF-M memory footprint by extracting the common components
+ shared by ``COSE_Mac0`` and ``COSE_Sign1`` but can make the design
+ over-complicated.
+
+.. note ::
+
+ Only HMAC is supported in current ``COSE_Mac0`` prototype.
+
+File structure
+==============
+
+New files are added to implement the functionalities listed above. The structure
+of files is shown in the table below.
+
+.. table:: New files in ``t_cose``
+ :widths: auto
+ :align: center
+
+ +---------------------+--------------------------------+----------------------------------------------+
+ | Directory | Files | Descriptions |
+ +=====================+================================+==============================================+
+ | ``src`` | ``t_cose_mac0_sign.c`` | Encode ``COSE_Mac0`` structure |
+ | +--------------------------------+----------------------------------------------+
+ | | ``t_cose_mac0_verify.c`` | Decode and verify ``COSE_Mac0`` structure. |
+ +---------------------+--------------------------------+----------------------------------------------+
+ | ``inc`` | ``t_cose_mac0_sign.h`` | Data type definitions and function |
+ | | | declarations of encoding and signing |
+ | | | ``COSE_Mac0`` message. |
+ | +--------------------------------+----------------------------------------------+
+ | | ``t_cose_mac0_verify.h`` | Data type definitions and function |
+ | | | declarations of verifying ``COSE_Mac0`` |
+ | | | message. |
+ +---------------------+--------------------------------+----------------------------------------------+
+
+Other ``t_cose`` files may also be changed to add ``COSE_Mac0`` associated data
+types and function declarations.
+
+HMAC operations are added in ``crypto_adapters/t_cose_psa_crypto.c``.
+Preprocessor flags are added to select corresponding crypto for COSE message
+signing and verification.
+
+ - ``T_COSE_ENABLE_SIGN1`` selects ECDSA and Hash operations for
+ ``COSE_Sign1``.
+ - ``T_COSE_ENABLE_MAC0`` selects HMAC operations for ``COSE_Mac0``.
+
+Encoding COSE_Mac0
+==================
+
+Following ``COSE_Sign1`` implementation, ``COSE_Mac0`` encoding exports similar
+functions to Initial Attestation secure service.
+The major functions are listed below.
+
+Initialize signing context
+--------------------------
+
+``t_cose_mac0_sign_init()`` initializes ``COSE_Mac0`` signing context and
+configures option flags and algorithm used in signing.
+
+.. code-block:: c
+
+ static void
+ t_cose_mac0_sign_init(struct t_cose_mac0_sign_ctx *me,
+ int32_t option_flags,
+ int32_t cose_algorithm_id);
+
+The ``COSE_Mac0`` signing context is defined as
+
+.. code-block:: c
+
+ struct t_cose_mac0_sign_ctx {
+ /* Private data structure */
+ uint8_t protected_parameters_buffer[
+ T_COSE_MAC0_MAX_SIZE_PROTECTED_PARAMETERS];
+ struct q_useful_buf_c protected_parameters; /* The encoded protected parameters */
+ int32_t cose_algorithm_id;
+ struct t_cose_key signing_key;
+ int32_t option_flags;
+ struct q_useful_buf_c kid;
+ ...
+ };
+
+Set signing key
+---------------
+
+``t_cose_mac0_set_signing_key()`` sets the key used in ``COSE_Mac0`` signing.
+Optional ``kid``, as a key identifer, will be encoded into ``COSE_Mac0`` Header
+unprotected bucket.
+
+.. code-block:: c
+
+ static void
+ t_cose_mac0_set_signing_key(struct t_cose_mac0_sign_ctx *me,
+ struct t_cose_key signing_key,
+ struct q_useful_buf_c kid);
+
+Encode Header parameters
+------------------------
+
+``t_cose_mac0_encode_parameters()`` encodes the ``COSE_Mac0`` Header parameters
+and outputs the encoded context to ``cbor_encode_ctx``.
+
+.. code-block:: c
+
+ enum t_cose_err_t
+ t_cose_mac0_encode_parameters(struct t_cose_mac0_sign_ctx *context,
+ QCBOREncodeContext *cbor_encode_ctx);
+
+Calculate and add authentication tag
+------------------------------------
+
+``t_cose_mac0_encode_tag()`` calculates the authentication tag and finishes the
+``COSE_Mac0`` message.
+
+.. code-block:: c
+
+ enum t_cose_err_t
+ t_cose_mac0_encode_tag(struct t_cose_mac0_sign_ctx *context,
+ QCBOREncodeContext *cbor_encode_ctx);
+
+Decoding COSE_Mac0
+==================
+
+Following ``COSE_Sign1`` implementation, ``COSE_Mac0`` decoding exports similar
+functions to test suite of Initial Attestation.
+The major functions are listed below.
+
+Initialize verification context
+-------------------------------
+
+``t_cose_mac0_verify_init()`` initializes ``COSE_Mac0`` verification context and
+configures option flags in verification.
+
+.. code-block:: c
+
+ static void
+ t_cose_mac0_verify_init(struct t_cose_mac0_verify_ctx *context,
+ int32_t option_flags);
+
+The ``COSE_Mac0`` verification context is defined as
+
+.. code-block:: c
+
+ struct t_cose_mac0_verify_ctx {
+ /* Private data structure */
+ struct t_cose_key verification_key;
+ int32_t option_flags;
+ };
+
+Set verification key
+--------------------
+
+``t_cose_mac0_set_verify_key()`` sets the key for verifying ``COSE_Mac0``
+authentication tag.
+
+.. code-block:: c
+
+ static void
+ t_cose_mac0_set_verify_key(struct t_cose_mac0_verify_ctx *context,
+ struct t_cose_key verify_key);
+
+Decode and verify COSE_Mac0
+---------------------------
+
+``t_cose_mac0_verify()`` decodes the ``COSE_Mac0`` structure and verifies the
+authentication tag.
+
+.. code-block:: c
+
+ enum t_cose_err_t
+ t_cose_mac0_verify(struct t_cose_mac0_verify_ctx *context,
+ struct q_useful_buf_c cose_mac0,
+ struct q_useful_buf_c *payload,
+ struct t_cose_parameters *parameters);
+
+Short-circuit tagging
+=====================
+
+If ``T_COSE_OPT_SHORT_CIRCUIT_TAG`` option is enabled, ``COSE_Mac0`` encoding
+will hash the ``COSE_Mac0`` content and add the hash output as an authentication
+tag. It is useful when critical symmetric IAK is unavailable or cannot be
+accessed, perhaps because it has not been provisioned or configured for the
+particular device. It is only for test and must not be used in actual use case.
+The ``kid`` parameter will either be skipped in ``COSE_Mac0`` Header.
+
+If ``T_COSE_OPT_ALLOW_SHORT_CIRCUIT`` option is enabled, ``COSE_Mac0`` decoding
+will only verify the hash output, without requiring symmetric key for
+authentication tag verification.
+
+***************
+TF-M Test suite
+***************
+
+Symmetric Initial Attestation adds dedicated non-secure and secure test suites.
+The test suites also follow asymmetric Initial Attestation test suites
+implementation but optimize the memory footprint.
+Symmetric Initial Attestation non-secure and secure test suites request Initial
+Attestation secure service to generate IATs. After IATs are generated
+successfully, test suites decode IATs and parse the claims.
+Secure test suite also verifies the authentication tag in ``COSE_Mac0``
+structure.
+
+Symmetric Initial Attestation implements its dedicated
+``attest_token_decode_validate_token()`` in ``attest_symmetric_iat_decoded.c``
+to perform IAT decoding required by test suites.
+If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected,
+``attest_symmetric_iat_decoded.c`` is included in build.
+Otherwise, asymmetric Initial Attestation dedicated implementations are included
+instead.
+
+The workflow of symmetric Initial Attestation dedicated
+``attest_token_decode_validate_token()`` is shown below.
+
+.. _iat-decode-figure:
+
+.. figure:: /design_docs/media/symmetric_initial_attest/iat_decode.png
+ :align: center
+
+ Workflow in symmetric Initial Attestation ``attest_token_decode_validate_token()``
+
+If the decoding is required from secure test suite,
+``attest_token_decode_validate_token()`` will fetch symmetric IAK to verify the
+authentication tag in ``COSE_Mac0`` structure.
+If the decoding is required from non-secure test suite,
+``attest_token_decode_validate_token()`` will decode ``COSE_Mac0`` only by
+setting ``T_COSE_OPT_DECODE_ONLY`` option flag. Non-secure must not access the
+symmetric IAK.
+
+********
+HAL APIs
+********
+
+HAL APIs are summarized below.
+
+Fetch device symmetric IAK
+==========================
+
+``tfm_plat_get_symmetric_iak()`` fetches device symmetric IAK.
+
+ .. code-block:: c
+
+ enum tfm_plat_err_t tfm_plat_get_symmetric_iak(uint8_t *key_buf,
+ size_t buf_len,
+ size_t *key_len,
+ psa_algorithm_t *key_alg);
+
+ **Parameters:**
+
+ +-------------+-----------------------------------------------------------+
+ | ``key_buf`` | Buffer to store the symmetric IAK. |
+ +-------------+-----------------------------------------------------------+
+ | ``buf_len`` | The length of ``key_buf``. |
+ +-------------+-----------------------------------------------------------+
+ | ``key_len`` | The length of the symmetric IAK. |
+ +-------------+-----------------------------------------------------------+
+ | ``key_alg`` | The key algorithm. Only HMAC SHA-256 is supported so far. |
+ +-------------+-----------------------------------------------------------+
+
+It returns error code specified in ``enum tfm_plat_err_t``.
+
+Get symmetric IAK key identifier
+================================
+
+``attest_plat_get_symmetric_iak_id()`` gets the key identifier of the symmetric
+IAK as the ``kid`` parameter in COSE Header.
+
+Optional if device doesn't install a key identifier for symmetric IAK.
+
+ .. code-block:: c
+
+ enum tfm_plat_err_t attest_plat_get_symmetric_iak_id(void *kid_buf,
+ size_t buf_len,
+ size_t *kid_len);
+
+ **Parameters:**
+
+ +-------------+-------------------------------------+
+ | ``kid_buf`` | Buffer to store the IAK identifier. |
+ +-------------+-------------------------------------+
+ | ``buf_len`` | The length of ``kid_buf``. |
+ +-------------+-------------------------------------+
+ | ``kid_len`` | The length of the IAK identifier. |
+ +-------------+-------------------------------------+
+
+It returns error code specified in ``enum tfm_plat_err_t``.
+
+*********
+Reference
+*********
+
+.. [1] `PSA Attestation API 1.0 (ARM IHI 0085) <https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Implement/IHI0085-PSA_Attestation_API-1.0.2.pdf?revision=eef78753-c77e-4b24-bcf0-65596213b4c1&la=en&hash=E5E0353D612077AFDCE3F2F3708A50C77A74B2A3>`_
+
+.. [2] :doc:`Trusted Firmware-M Profile Small Design </configuration/profiles/tfm_profile_small>`
+
+.. [3] :doc:`Initial Attestation Service Integration Guide </integration_guide/services/tfm_attestation_integration_guide>`
+
+.. [4] `HMAC: Keyed-Hashing for Message Authentication <https://tools.ietf.org/html/rfc2104>`_
+
+.. [5] `CBOR Object Signing and Encryption (COSE) <https://tools.ietf.org/html/rfc8152>`_
+
+----------------
+
+*Copyright (c) 2020-2022 Arm Limited. All Rights Reserved.*
diff --git a/docs/design_docs/services/tfm_crypto_design.rst b/docs/design_docs/services/tfm_crypto_design.rst
new file mode 100644
index 0000000..7106849
--- /dev/null
+++ b/docs/design_docs/services/tfm_crypto_design.rst
@@ -0,0 +1,192 @@
+Crypto Service design
+=====================
+
+:Author: Antonio de Angelis
+:Organization: Arm Limited
+:Contact: Antonio de Angelis <antonio.deangelis@arm.com>
+
+.. contents:: Table of Contents
+
+Abstract
+--------
+
+This document describes the design of the TF-M Cryptographic Secure Service
+(in short, TF-M Crypto service).
+
+Introduction
+------------
+
+The TF-M Crypto service provides an implementation of the PSA Crypto API
+in a PSA RoT secure partition in TF-M. It is based on Mbed Crypto, which
+is a reference implementation of the PSA Crypto API. For more details on
+the PSA Crypto API or the Mbed Crypto implementation, please refer
+directly to the ``mbed-crypto`` GitHub repository [1]_ .
+
+The service can be used by other services running in the SPE, or by
+applications running in the NSPE, to provide cryptographic
+functionalities.
+
+Components
+----------
+
+The TF-M Crypto service is implemented by a number of different software
+components, which are listed below:
+
+.. table:: Components table
+ :widths: auto
+
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | **Component name** | **Description** | **Location** |
+ +=============================+===============================================================+======================================================================+
+ | Client API interface | This module exports the client API of PSA Crypto to the users.| ``./interface/src/tfm_crypto_api.c`` |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Mbed Crypto | The Mbed Crypto library is used in the service as a | Needed as dependency at the same level of the TF-M folder, |
+ | | cryptographic library exposing the PSA Crypto API interface. | i.e. ``../mbed-crypto`` |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Init module | This module handles the initialisation of the service objects | ``./secure_fw/partitions/crypto/crypto_init.c`` |
+ | | during TF-M boot and provides the infrastructure to service | |
+ | | requests when TF-M is built for IPC model. | |
+ | | The dispatching mechanism of IPC requests is based on a look | |
+ | | up table of function pointers. | |
+ | | This design allows for better scalability and support of a | |
+ | | higher number of Secure functions with minimal overhead and | |
+ | | duplication of code. | |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Alloc module | This module handles the allocation of contexts for multipart | ``./secure_fw/partitions/crypto/crypto_alloc.c`` |
+ | | operations in the Secure world. | |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Service modules | These modules (AEAD, Asymmetric, Cipher, Key Deriv, Hash, Key,| ``./secure_fw/partitions/crypto/crypto_aead.c`` |
+ | | MAC) represent a thin layer which is in charge of servicing | ``./secure_fw/partitions/crypto/crypto_asymmetric.c`` |
+ | | the calls from the SPE/NSPE client API interfaces. | ``./secure_fw/partitions/crypto/crypto_cipher.c`` |
+ | | They provide parameter sanitation and context retrieval for | ``./secure_fw/partitions/crypto/crypto_key_derivation.c`` |
+ | | multipart operations, and dispatching to the corresponding | ``./secure_fw/partitions/crypto/crypto_hash.c`` |
+ | | library function exposed by Mbed Crypto for the desired | ``./secure_fw/partitions/crypto/crypto_key.c`` |
+ | | functionality. | ``./secure_fw/partitions/crypto/crypto_mac.c`` |
+ | | | ''./secure_fw/partitions/crypto/crypto_key_management.c'' |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Manifest | The manifest file is a description of the service components. | ``./secure_fw/partitions/crypto/manifest.yaml`` |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | CMake files and headers | The CMake files are used by the TF-M CMake build system to | ``./secure_fw/partitions/crypto/CMakeLists.inc`` |
+ | | build the service as part of the Secure FW build. The service | ``./secure_fw/partitions/crypto/CMakeLists.txt`` |
+ | | is built as a static library (``tfm_crypto.a``). | ``./interface/include/tfm_crypto_defs.h`` |
+ | | The build system allows to build as well the Mbed Crypto | ``./secure_fw/partitions/crypto/tfm_crypto_api.h`` |
+ | | library as part of the Secure FW build process and archive it | ``./secure_fw/partitions/crypto/tfm_crypto_signal.h`` |
+ | | with the static library of the Crypto service. | ``./secure_fw/partitions/crypto/spe_crypto.h`` |
+ | | The headers are used to export the public prototypes of the | |
+ | | functions in the Service modules ``tfm_crypto_api.h``, and | |
+ | | to provide the necessary defines (i.e. ``TFM_CRYPTO_SIG``). | |
+ | | In particular ``TFM_CRYPTO_SIG`` identifies the signal on | |
+ | | which the service handler waits for requests when the service | |
+ | | is built for IPC model. | |
+ | | The header available in the interface, ``tfm_crypto_defs.h`` | |
+ | | , contains types and defines for building the NSPE interface | |
+ | | as part of a Non-Secure application. | |
+ | | Finally, the ``crypto_spe.h`` header is used during the | |
+ | | build of the Mbed Crypto library, when the Mbed Crypto config | |
+ | | option ``MBEDTLS_PSA_CRYPTO_SPM`` is defined, to add a | |
+ | | custom prefix to the PSA API symbols so that duplication of | |
+ | | symbol names is avoided. | |
+ | | The prefix used for the PSA API symbols of the Mbed Crypto | |
+ | | library is chosen to be ``mbedcrypto__``. | |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Documentation | The integration guide contains the description of the TF-M | ``./user_guides/services/tfm_crypto_integration_guide.rst`` |
+ | | Crypto service modules and interfaces. | |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+
+The interaction between the different components is described by the
+following block diagram:
+
+.. figure:: /design_docs/media/tfm_crypto_design.png
+
+ Block diagram of the different components of the TF-M Crypto service. A
+ dotted line is used to indicate the interaction with a library.
+
+Note: in IPC model, the interaction between components is slightly
+different, as the Service modules are not called directly through the
+TF-M Secure Partition Manager but through the IPC handler which resides
+in the Init module.
+
+Service API description
+-----------------------
+
+Most of the APIs exported by the TF-M Crypto service (i.e. from the Service
+modules) have a direct correspondence with the PSA Crypto API. The Alloc and
+Init modules instead export some APIs which are specific to the TF-M Crypto
+service, and are available only to the Service modules or the SPM. For a
+detailed description of the prototypes please refer to the ``tfm_crypto_api.h``
+header.
+
+.. table:: Init and Alloc modules APIs
+ :widths: auto
+
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | **Function** | **Module** | **Caller** | **Scope** |
+ +================================+==============+=================+======================================================+
+ | tfm_crypto_init() | Init | SPM | Called during TF-M boot for initialisation. In IPC |
+ | | | | model, it calls the IPC service request handler. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | tfm_crypto_init_alloc() | Alloc | Init | Called by tfm_crypto_init(), it initialises the |
+ | | | | concurrent operation contexts storage area. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | tfm_crypto_operation_alloc() | Alloc | Service modules | It allocates a new operation context for a multipart |
+ | | | | operation. It returns an handle to the allocated |
+ | | | | context in secure memory. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | tfm_crypto_operation_lookup() | Alloc | Service modules | It retrieves a previously allocated operation context|
+ | | | | of a multipart operation, based on the handle given |
+ | | | | as input. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | tfm_crypto_operation_release() | Alloc | Service modules | It releases a previously allocated operation context |
+ | | | | of a multipart operation, based on the handle given |
+ | | | | as input. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+
+Configuration parameters
+------------------------
+
+The TF-M Crypto service exposes some configuration parameters to tailor
+the service configuration in terms of supported functionalities and
+hence FLASH/RAM size to meet the requirements of different platforms and
+use cases. These parameters can be provided via CMake parameters during
+the CMake configuration step and as a configuration header to allow the
+configuration of the Mbed Crypto library.
+
+.. table:: Configuration parameters table
+ :widths: auto
+
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | **Parameter** | **Type** | **Description** | **Scope** | **Default** |
+ +====================================+===========================+================================================================+=========================================+============================================================================+
+ | ``CRYPTO_ENGINE_BUF_SIZE`` | CMake build | Buffer used by Mbed Crypto for its own allocations at runtime. | To be configured based on the desired | 8096 (bytes) |
+ | | configuration parameter | This is a buffer allocated in static memory. | use case and application requirements. | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | ``CRYPTO_CONC_OPER_NUM`` | CMake build | This parameter defines the maximum number of possible | To be configured based on the desire | 8 |
+ | | configuration parameter | concurrent operation contexts (cipher, MAC, hash and key deriv)| use case and platform requirements. | |
+ | | | for multi-part operations, that can be allocated simultaneously| | |
+ | | | at any time. | | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | ``CRYPTO_IOVEC_BUFFER_SIZE`` | CMake build | This parameter applies only to IPC model builds. In IPC model, | To be configured based on the desired | 5120 (bytes) |
+ | | configuration parameter | during a Service call, input and outputs are allocated | use case and application requirements. | |
+ | | | temporarily in an internal scratch buffer whose size is | | |
+ | | | determined by this parameter. | | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | ``MBEDTLS_CONFIG_FILE`` | Configuration header | The Mbed Crypto library can be configured to support different | To be configured based on the | ``./lib/ext/mbedcrypto/mbedcrypto_config/tfm_mbedcrypto_config_default.h`` |
+ | | | algorithms through the usage of a a configuration header file | application and platform requirements. | |
+ | | | at build time. This allows for tailoring FLASH/RAM requirements| | |
+ | | | for different platforms and use cases. | | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | ``MBEDTLS_PSA_CRYPTO_CONFIG_FILE`` | Configuration header | This header file specifies which cryptographic mechanisms are | To be configured based on the | ``./lib/ext/mbedcrypto/mbedcrypto_config/crypto_config_default.h`` |
+ | | | available through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG | application and platform requirements. | |
+ | | | is enabled, and is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is | | |
+ | | | disabled. | | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+
+References
+----------
+
+.. [1] ``mbed-crypto`` repository which holds the PSA Crypto API specification and the Mbed Crypto reference implementation: \ https://github.com/Mbed-TLS
+
+
+--------------
+
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/tfm_fwu_service.rst b/docs/design_docs/services/tfm_fwu_service.rst
new file mode 100644
index 0000000..f97dfd4
--- /dev/null
+++ b/docs/design_docs/services/tfm_fwu_service.rst
@@ -0,0 +1,368 @@
+#######################
+Firmware Update Service
+#######################
+
+:Author: Sherry Zhang
+:Organization: Arm Limited
+:Contact: Sherry Zhang <Sherry.Zhang2@arm.com>
+
+.. contents:: Table of Contents
+ :depth: 3
+
+***************************************
+Introduction of Firmware Update service
+***************************************
+The Firmware Update(FWU) service provides the functionality of updating firmware
+images. It provides a standard interface for updating firmware and it is
+platform independent. TF-M defines a shim layer to support cooperation between
+bootloader and FWU service.
+
+This partition supports the following features:
+
+- Query the firmware store information.
+- Image preparation: prepare a new firmware image in the component's firmware store.
+- Image installation: install prepared firmware images on all components that have been prepared for installation.
+- Image trial: manage a trial of new firmware images atomically on all components that are in TRIAL state.
+
+A typical flow through the component states is shown below [1]_.
+
+.. figure:: /design_docs/media/fwu-states.svg
+ :scale: 65 %
+ :align: center
+ :name: The component state model transitions.
+
+**********
+Components
+**********
+The structure of the TF-M Firmware Update service is listed below:
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | **Component name** | **Description** | **Location** |
+ +=============================+===============================================================+=======================================================================================+
+ | Client API interface | This module exports the client API of PSA Firmware Update to | ``./interface/src/tfm_fwu_api.c`` |
+ | | the users. | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | Manifest | The manifest file is a description of the service components. | ``./secure_fw/partitions/firmware_update/tfm_firmware_update.yaml`` |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | NSPE client API interface | This module exports the client API of PSA Firmware Update to | ``./interface/src/tfm_fwu_api.c`` |
+ | | the NSPE(i.e. to the applications). | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | IPC request handlers | This module handles all the secure requests in IPC model. | ``./secure_fw/partitions/firmware_update/tfm_fwu_req_mngr.c`` |
+ | | It maitains the image state context and calls the image ID | |
+ | | converter to achieve the firmware update functionalities. | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | Shim layer between FWU and | This module provides the APIs with the functionality of | ``./secure_fw/partitions/firmware_update/bootloader/tfm_bootloader_fwu_abstraction.h``|
+ | bootloader | operating the bootloader to cooperate with the Firmware Update| |
+ | | service | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | Shim layer example based on | This module is the implementation of the shim layer between | ``./secure_fw/partitions/firmware_update/bootloader/mcuboot/tfm_mcuboot_fwu.c`` |
+ | MCUboot | FWU and bootloader based on MCUboot. | |
+ | | | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+
+***********************
+Service API description
+***********************
+This service follows the PSA Firmware Update API spec of version 1.0 [1]_. Please refer to
+Firmware Update spec for the detailed description.
+
+*************************************
+Shim Layer between FWU and bootloader
+*************************************
+The firmware update operations are achieved by calling the shim layer APIs
+between bootloader and FWU.
+
+Shim layer introduction
+=======================
+This shim layer provides the APIs with the functionality of operating the
+bootloader to cooperate with the Firmware Update service. This shim layer
+is decoupled from bootloader implementation. Users can specify a specific
+bootloader by setting ``TFM_FWU_BOOTLOADER_LIB`` build configuration and
+adding the specific build scripts into that file. By default, the MCUboot
+is chosen as the bootloader.
+
+Interfaces of the shim Layer
+============================
+
+fwu_bootloader_init(function)
+-----------------------------
+Prototype
+^^^^^^^^^
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_init(void);
+
+Description
+^^^^^^^^^^^
+Bootloader related initialization for the firmware update. It reads
+some necessary shared data from the memory if needed. It initializes
+the flash drivers defined in FLASH_DRIVER_LIST. Platform can define
+FLASH_DRIVER_LIST in flash_layout.h to overload the default driver list.
+
+Parameters
+^^^^^^^^^^
+ N/A
+
+fwu_bootloader_staging_area_init(function)
+------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_staging_area_init(psa_fwu_component_t component,
+ const void *manifest,
+ size_t manifest_size);
+
+**Description**
+
+The component is in READY state. Prepare the staging area of the component for image download.
+For example, initialize the staging area, open the flash area, and so on.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+- ``manifest``: A pointer to a buffer containing a detached manifest for the update.
+ If the manifest is bundled with the firmware image, manifest must be NULL.
+- ``manifest_size``: Size of the manifest buffer in bytes.
+
+fwu_bootloader_load_image(function)
+-----------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
+ size_t image_offset,
+ const void *block,
+ size_t block_size);
+
+**Description**
+
+Load the image into the target component.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+- ``image_offset``: The offset of the image being passed into block, in bytes.
+- ``block``: A buffer containing a block of image data. This might be a complete image or a subset.
+- ``block_size``: Size of block.
+
+fwu_bootloader_install_image(function)
+---------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_install_image(psa_fwu_component_t *candidates,
+ uint8_t number);
+
+**Description**
+
+Check the authenticity and integrity of the image. If a reboot is required to
+complete the check, then mark this image as a candidate so that the next time
+bootloader runs it will take this image as a candidate one to bootup. Return
+the error code PSA_SUCCESS_REBOOT.
+
+**Parameters**
+
+- ``candidates``: A list of components in CANDIDATE state.
+- ``number``: Number of components in CANDIDATE state.
+
+fwu_bootloader_mark_image_accepted(function)
+--------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_mark_image_accepted(const psa_fwu_component_t *trials,
+ uint8_t number);
+
+**Description**
+
+Call this API to mark the TRIAL(running) image in component as confirmed to avoid
+revert when next time bootup. Usually, this API is called after the running
+images have been verified as valid.
+
+**Parameters**
+
+- ``trials``: A list of components in TRIAL state.
+- ``number``: Number of components in TRIAL state.
+
+fwu_bootloader_reject_staged_image(function)
+--------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component);
+
+**Description**
+
+The component is in STAGED state. Call this API to Uninstall the staged image in the
+component so that this image will not be treated as a candidate next time bootup.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+
+fwu_bootloader_reject_trial_image(function)
+--------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_reject_trial_image(psa_fwu_component_t component);
+
+**Description**
+
+The component is in TRIAL state. Mark the running image in the component as rejected.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+
+fwu_bootloader_clean_component(function)
+----------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_clean_component(psa_fwu_component_t component);
+
+**Description**
+
+The component is in FAILED or UPDATED state. Clean the staging area of the component.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+
+fwu_bootloader_get_image_info(function)
+---------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_get_image_info(psa_fwu_component_t component,
+ bool query_state,
+ bool query_impl_info,
+ psa_fwu_component_info_t *info);
+
+**Description**
+
+Get the image information of the given bootloader_image_id in the staging area
+or the running area.
+
+**Parameters**
+
+ - ``component``: The identifier of the target component in bootloader.
+ - ``query_state``: Whether query the 'state' field of psa_fwu_component_info_t.
+ - ``query_impl_info``: Whether Query 'impl' field of psa_fwu_component_info_t.
+ - ``info``: Buffer containing return the component information.
+
+******************************************
+Additional shared data between BL2 and SPE
+******************************************
+An additional TLV area "image version" is added into the shared memory between
+BL2 and TF-M. So that the firmware update partition can get the image version.
+Even though the image version information is also included in the ``BOOT RECORD``
+TLV area which is encoded by CBOR, adding a dedicated ``image version`` TLV area
+is preferred to avoid involving the CBOR encoder which can increase the code
+size. The FWU partition will read the shared data at the partition
+initialization.
+
+*********************************************
+Build configurations related to FWU partition
+*********************************************
+- ``TFM_PARTITION_FIRMWARE_UPDATE`` Controls whether FWU partition is enabled or not.
+- ``TFM_FWU_BOOTLOADER_LIB`` Bootloader configure file for FWU partition.
+- ``TFM_CONFIG_FWU_MAX_WRITE_SIZE`` The maximum permitted size for block in psa_fwu_write, in bytes.
+- ``TFM_FWU_BUF_SIZE`` Size of the FWU internal data transfer buffer (defaults to
+ TFM_CONFIG_FWU_MAX_WRITE_SIZE if not set).
+- ``FWU_STACK_SIZE`` The stack size of FWU Partition.
+- ``FWU_DEVICE_CONFIG_FILE`` The device configuration file for FWU partition. The default value is
+ the configuration file generated for MCUboot. The following macros should be defined in the
+ configuration file:
+
+ - ``FWU_COMPONENT_NUMBER`` The number of components on the device.
+
+ .. Note::
+
+ In this design, component ID ranges from 0 to ``FWU_COMPONENT_NUMBER`` - 1.
+
+ - ``FWU_SUPPORT_TRIAL_STATE`` Whether TRIAL component state is supported.
+- ``TEST_NS_FWU`` FWU nonsecure tests switch.
+- ``TEST_S_FWU`` FWU secure tests switch.
+
+ .. Note::
+
+ The running image which supports revert mechanism should be confirmed before initiating a
+ firmware update process. For example, if the running image is built with
+ ``-DMCUBOOT_UPGRADE_STRATEGY=SWAP_USING_MOVE``, the image should be confirmed either by
+ adding ``-DMCUBOOT_CONFIRM_IMAGE=ON`` build option or by calling ``psa_fwu_accept()`` API
+ before initiating a firmware update process. Otherwise, ``PSA_ERROR_BAD_STATE`` will be
+ returned by ``psa_fwu_start()``.
+
+*************************************
+Limitations of current implementation
+*************************************
+Currently, the MCUboot based implementation does not record image update results like failure or
+success. And FWU partition does not detect failure errors in bootloader installation. If an image
+installation fails in the bootloader and the old image still runs after reboot, ``PSA_FWU_READY``
+state will be returned by ``psa_fwu_query()`` after reboot.
+
+Currently, image download recovery after a reboot is not supported. If a reboot happens in image
+preparation, the downloaded image data will be ignored after the reboot.
+
+***********************************
+Benefits Analysis on this Partition
+***********************************
+
+Implement the FWU functionality in the non-secure side
+======================================================
+The APIs listed in PSA Firmware Update API spec [1]_ can also be implemented in
+the non-secure side.
+
+Pros and Cons for implementing FWU APIs in secure side
+======================================================
+
+Pros
+----
+- It protects the image in the passive or staging area from being tampered with
+ by the NSPE. Otherwise, a malicious actor from NSPE can tamper the image
+ stored in the non-secure area to break image update.
+
+- It protects secure image information from disclosure. In some cases, the
+ non-secure side shall not be permitted to get secure image information.
+
+- It protects the active image from being manipulated by NSPE. Some bootloader
+ supports testing the image. After the image is successfully installed and
+ starts to run, the user should set the image as permanent image if the image
+ passes the test. To achieve this, the area of the active image needs to be
+ accessed. In this case, implementing FWU service in SPE can prevent NSPE
+ from manipulating the active image area.
+
+- On some devices, such as the Arm Musca-B1 board, the passive or staging area
+ is restricted as secure access only. In this case, the FWU partition should
+ be implemented in the secure side.
+
+Cons
+----
+- It increases the image size of the secure image.
+- It increases the execution latency and footprint. Compared to implementing
+ FWU in NSPE directly, calling the Firmware Update APIs which are implemented
+ in the secure side increases the execution latency and footprint.
+- It can increase the attack surface of the secure runtime.
+
+Users can decide whether to call the FWU service in TF-M directly or implement
+the Firmware Update APIs in the non-secure side based on the pros and cons
+analysis above.
+
+*********
+Reference
+*********
+
+.. [1] `PSA Firwmare Update API <https://arm-software.github.io/psa-api/fwu/1.0/>`_
+
+--------------
+
+*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/tfm_its_512_flash.rst b/docs/design_docs/services/tfm_its_512_flash.rst
new file mode 100644
index 0000000..205375a
--- /dev/null
+++ b/docs/design_docs/services/tfm_its_512_flash.rst
@@ -0,0 +1,103 @@
+###############################################################
+Add support for block-aligned flash in Internal Trusted Storage
+###############################################################
+
+:Author: Minos Galanakis
+:Organization: Arm Limited
+:Contact: Minos Galanakis <minos.galanakis@arm.com>
+
+Abstract
+========
+
+The proposal is describing a mechanism to enable the use of larger flash
+devices, imposing a requirement for word-aligned full-block program operations,
+in Trusted Firmware-M.
+
+
+Requirements
+============
+
+- Allow page-aligned writes for up to 512 Bytes per page.
+- Guarantee data integrity and power-failure reliability.
+- Do not alter existing supported platform behaviour.
+
+Current implementation
+======================
+
+In the current ITS filesystem design, each filesystem create or write operation
+requires two flash blocks to be updated: first the data block and then the
+metadata block. Buffering is avoided as much as possible to reduce
+RAM requirements.
+
+However, if the ITS_FLASH_PROGRAM_UNIT is 512 Bytes then the data will have to
+stored in a temporary memory location in order to be able to write
+that much data in one-shot.
+
+Proposed implementation overview
+================================
+
+1. A new block-sized static buffer should be added to its_flash.c when
+ ``ITS_FLASH_PROGRAM_UNIT`` is larger than currently supported.
+2. Methods calling the flash API such as ``its_flash_write()`` or
+ ``its_flash_block_to_block_move()`` will populate the buffer instead of
+ directly programming the flash.
+3. A new method ``its_flash_flush()``, should be provided in order to flush
+ the block buffer to the device.
+4. ``its_flash_flush()`` should be called twice: Once after a data block
+ update and once more after the metadata block update is completed.
+5. The proposed design should require that the data block update is always
+ completed before the metadata block update starts
+6. Writes to the block buffer should be atomic, and guarded against corruption
+ by data from different blocks.
+
+Considerations
+==============
+
+- The proposed implementation will increase the RAM usage of ITS by the size
+ of a block, only for platforms which require block-aligned writes.
+- Currently power-failure is detected by software by incrementing an 8-bit
+ metadata header field (``swap_count``), as the last written byte. When the
+ proposed block-buffer is used, the block is programmed in one-shot and the
+ order the bytes are written on the physical device, is hardware dependent.
+- A set of guarantees are required by the supported flash ECC devices.
+ The device's flash APIs should provide a mechanism to capture and raise
+ incomplete program operations, as well as write bytes in a sequential order.
+
+For example, if a board powers down through a 512 page program operation, the
+next read operation should return an error rather than read invalid data.
+
+Functional flow diagram
+=======================
+
+The logic of the proposal is described in the following diagram
+
+.. code-block:: rst
+
+ |----------------------|
+ | data write() |
+ |----------------------|
+ | | |------------------------------|
+ |-> | its_flash_write | ---> | data[] -> its_block_buffer[] |
+ | | | |------------------------------|
+ | |----------------------|
+ | | | |------------------------------------|
+ | | its_flash_flush | ---> | its_block_buffer[] -> flash dev IO |
+ | | | |------------------------------------|
+ | |----------------------|
+ | |
+ | ------------------------------------
+ | |
+ | V
+ | |----------------------| |--------------------------|
+ | | data write() complete| | metadata write() complete|
+ | |----------------------| |--------------------------|
+ | <-| Metadata write() | |
+ |----------------------| |
+ V
+ |--------------------------|
+ | Operation Complete |
+ |--------------------------|
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/tfm_its_service.rst b/docs/design_docs/services/tfm_its_service.rst
new file mode 100644
index 0000000..e170504
--- /dev/null
+++ b/docs/design_docs/services/tfm_its_service.rst
@@ -0,0 +1,285 @@
+======================================
+Internal Trusted Storage (ITS) Service
+======================================
+
+:Author: Jamie Fox
+:Organization: Arm Limited
+:Contact: Jamie Fox <jamie.fox@arm.com>
+
+.. toctree::
+ :maxdepth: 1
+
+ Block-aligned flash <tfm_its_512_flash.rst>
+
+PSA Internal Trusted Storage
+============================
+PSA Internal Trusted Storage (ITS) is a PSA RoT Service for storing the most
+security-critical device data (e.g. cryptographic keys) in internal storage,
+which is trusted to provide data confidentiality and authenticity. This
+contrasts with PSA Protected Storage, which is an Application RoT service that
+allows larger data sets to be stored securely in external flash, with the option
+for encryption, authentication and rollback protection to protect the
+data-at-rest.
+
+Current TF-M Secure Storage
+===========================
+Currently, the TF-M Secure Storage service implements PSA Protected Storage
+version 1.0-beta2. There is not yet an implementation of PSA Internal Trusted
+Storage in TF-M.
+
+New TF-M service
+================
+The proposal is to implement the *PSA Internal Trusted Storage API* with the
+*TF-M Internal Trusted Storage service*. It can be abbreviated to *TF-M ITS
+service* in general and to ``its`` in code. This name has the advantage of
+making clear the correspondence between the service and the API it implements.
+
+If this name is adopted, then it may make sense to rename the *Secure Storage
+service* to the *Protected Storage service* in the future to match. Then "secure
+storage" could refer to the two services as a collective.
+
+The TF-M ITS service will implement PSA ITS version 1.0. It will be provided by
+a separate partition to Protected Storage, for a couple of reasons:
+
+- To permit isolation between the services.
+
+ - ITS is a PSA RoT Service, while Protected Storage is an Application RoT
+ Service.
+
+- To avoid circular dependencies.
+
+ - The PSA Firmware Framework does not permit circular dependencies between
+ partitions, which would occur if Protected Storage and ITS were provided by
+ the same partition. Protected Storage depends on Crypto, which in turn
+ depends on ITS.
+
+The existing SST filesystem will be reused to provide the backend of the
+service, with the flash layer modified to direct storage to internal flash,
+rather than external.
+
+Compared to Protected Storage, encryption, authentication and rollback
+protection are not required, so the SST encrypted object layer and the crypto
+and NV counter interfaces are not required. The rollback protection feature of
+the object table is also not required.
+
+Code structure
+==============
+The code structure of the service will be as follows:
+
+TF-M repo:
+
+``interface/``
+
+- ``include/psa/internal_trusted_storage.h`` - PSA ITS API
+- ``src/tfm_its_api.c`` - PSA ITS API implementation for NSPE
+
+``secure_fw/ns_callable/tfm_veneers.c`` - ITS veneers (auto-generated from
+manifest)
+
+``secure_fw/partitions/internal_trusted_storage/``
+
+- ``tfm_internal_trusted_storage.yaml`` - Partition manifest
+- ``tfm_its_secure_api.c`` - PSA ITS API implementation for SPE
+- ``tfm_its_req_mngr.c`` - Uniform secure functions and IPC request handlers
+- ``tfm_internal_trusted_storage.h`` - TF-M ITS API (with client_id parameter)
+- ``tfm_internal_trusted_storage.c`` - TF-M ITS implementation, using the
+ flash_fs as a backend
+- ``flash_fs/`` - Filesystem
+- ``flash/`` - Flash interface
+
+tf-m-tests repo:
+
+``test/secure_fw/suites/its/``
+
+- ``non_secure/psa_its_ns_interface_testsuite.c`` - Non-secure interface tests
+- ``secure/psa_its_s_interface_testsuite.c`` - Secure interface tests
+
+TF-M ITS implementation
+-----------------------
+The following APIs will be exposed by ``tfm_internal_trusted_storage.h``::
+
+ psa_status_t tfm_its_init(void);
+
+ psa_status_t tfm_its_set(int32_t client_id,
+ psa_storage_uid_t uid,
+ size_t data_length,
+ const void *p_data,
+ psa_storage_create_flags_t create_flags);
+
+ psa_status_t tfm_its_get(int32_t client_id,
+ psa_storage_uid_t uid,
+ size_t data_offset,
+ size_t data_size,
+ void *p_data,
+ size_t *p_data_length);
+
+ psa_status_t tfm_its_get_info(int32_t client_id,
+ psa_storage_uid_t uid,
+ struct psa_storage_info_t *p_info);
+
+ psa_status_t tfm_its_remove(int32_t client_id,
+ psa_storage_uid_t uid);
+
+That is, the TF-M ITS APIs will have the same prototypes as the PSA ITS APIs,
+but with the addition of a ``client_id`` parameter, which will be passed from
+the ITS request manager. A ``tfm_its_init`` function will also be present, which
+will be called at initialisation time and not exposed through a veneer or SID.
+
+The implementation in ``tfm_internal_trusted_storage.c`` must validate the
+parameters (excepting memory references, which are validated by the SPM),
+translate the UID and client ID into a file ID and then make appropriate calls
+to the filesystem layer. It must also take care ensure that any PSA Storage
+flags associated with the UID are honoured.
+
+Filesystem
+----------
+The ITS filesystem will be copied and modified from the SST filesystem. The
+modifications required will be to rename symbols from ``sst`` to ``its`` and to
+update the implementation to be aligned with the latest version of the PSA
+Storage spec (which consists mainly of moving to the ``psa_status_t`` error type
+and using common error codes from ``psa/error.h``).
+
+The filesystem will also be modified to align the size of each file stored to
+the alignment requirement exposed by the flash interface, by adding appropriate
+padding.
+
+The filesystem code will be de-duplicated again once the ITS service is
+implemented (see below).
+
+Flash layer
+-----------
+The flash layer will be copied from SST, and modified to direct writes to the
+internal flash device. It too needs to be updated to use ``psa_status_t`` error
+types.
+
+Platform layer
+--------------
+The TF-M platform layer must be be updated to distinguish between the external
+flash device used for Protected Storage and internal flash device used for ITS.
+A flash region for the relevant storage service needs to be allocated in each.
+
+On test platforms these may just be two distinct regions of the same flash
+device, but in general they will separate devices with their own drivers.
+
+Detailed design considerations
+==============================
+
+Mapping UID onto file ID
+------------------------
+The ITS APIs identify assets with 64-bit UIDs, to which the ITS service must
+append the 32-bit client ID of the calling partition for access control. The
+existing filesystem uses 32-bit file IDs to identify files, so some mapping
+would be required to convert between the identifiers.
+
+SST uses the object table to do the mapping from client ID, UID pairs to file
+IDs, which means making an extra filesystem read/write for each get/set
+operation. This mapping has minimal overhead for SST though, because object
+table lookups are already required for rollback protection.
+
+For ITS, no rollback protection feature is required, so there are two options:
+
+- Keep a simplified version of the SST object table that just maps from
+ (client ID, UID) to file ID
+
+- Modify the filesystem to take (at least) 96-bit file IDs, in the form of a
+ fixed-length char buffer.
+
+The advantage of the former is that it would require no extra modification to
+the existing filesystem code, and the existing SST object table could be cut
+down for ITS. However, it would mean that every ITS request would invoke twice
+the number of filesystem operations, increasing latency and flash wear. The code
+size of the ITS partition would be increased, as would RAM usage as the table
+would need to be read into RAM.
+
+The latter option would make the filesystem slightly more complex: the size of a
+metadata entry would be increased by 64-bits and the 96-bit fids would need to
+be copied and compared with ``memcpy`` and ``memcmp`` calls. On the other hand,
+mapping onto file IDs would incur only the cost of copying the UID and client ID
+values into the file ID buffer.
+
+A third, even more general, solution would be to use arbitrary-length
+null-terminated strings as the file IDs. This is the standard solution in
+full-featured filesystems, but we do not currently require this level of
+complexity in secure storage.
+
+With this in mind, the proposed option is the second.
+
+Storing create flags
+--------------------
+The ITS APIs provide a 32-bit ``create_flags`` parameter, which contains bit
+flags that determine the properties of the stored data. Only one flag is
+currently defined for ITS: ``PSA_STORAGE_FLAG_WRITE_ONCE``, which prevents a UID
+from being modified or deleted after it is set for the first time.
+
+There are two places that these flags could be stored: in the file data or as
+part of the file metadata.
+
+For the first option, the ITS implementation would need to copy to the flags
+into the buffer containing the data, and adjust the size accordingly, for each
+set operation, and the reverse for each get. Every get_info operation would need
+to read some of the file data, rather than just the metadata, implying a second
+flash read. A potential downside is that many of the cryptographic assets stored
+in ITS will be aligned to power-of-two sizes; adding an extra 32-bits would
+misalign the size, which may reduce flash performance or necessitate adding
+padding to align to the flash page size.
+
+To implement the second option, a 32-bit ``flag`` field would be added to the
+filesystem's metadata structure, whose interpretation is defined by the user.
+This field would clearly be catered towards the PSA Storage APIs, even if
+nominally generic, and alternative filesystems may not have any such field.
+However, it is a more intuitive solution and would simplify both flash alignment
+and get_info operations.
+
+Overall, it seems more beneficial to store the flags in the metadata, so this is
+the proposed solution.
+
+Code sharing between Protected Storage and ITS
+----------------------------------------------
+To de-duplicate the filesystem code used by both Protected Storage and ITS, it
+is proposed that Protected Storage calls ITS APIs as its backend filesystem.
+
+Protected Storage essentially becomes an encryption, authentication and rollback
+protection layer on top of ITS. It makes IPC requests or secure function calls
+to the ITS service to do filesystem operations on its behalf.
+
+This has a couple of advantages:
+
+- It shrinks Protected Storage's stack size, because the filesystem and flash
+ layer stack is only in ITS.
+
+- It automatically solves the problem of ensuring mutual exclusion in the
+ filesystem and flash layers when Protected Storage and ITS are called
+ concurrently. The second request to ITS will just be made to wait by the SPM.
+
+The disadvantage of this approach is that it will increase the latency of
+Protected Storage requests, due to the extra overhead associated with making a
+second IPC request or secure function call. It also limits Protected Storage to
+using only the ITS APIs, unless extra veneers are added solely for Protected
+Storage to use. This, for example, prevents Protected Storage from doing partial
+writes to file without reading and re-writing the whole file.
+
+ITS will need to be modified to direct calls from Protected Storage to a
+different flash device. It can use the client ID to detect when the caller is
+Protected Storage, and pass down the identity of the flash device to use to the
+flash layer, which then calls the appropriate driver.
+
+An open question is what to do if Protected Storage itself wants to store
+something in internal storage in the future (e.g. rollback counters, hash
+tree/table or top hash). A couple of possible solutions would be:
+
+- Divide up the UIDs, so certain UIDs from Protected Storage refer to assets in
+ internal storage, and others to ones in external storage.
+
+- Use the ``type`` field of ``psa_call`` in IPC model to distinguish between
+ internal and external storage requests.
+
+The other option for code sharing would be for Protected Storage and ITS to
+directly share filesystem code, which would be placed in a shared code region.
+With this approach, mutual exclusion to the flash device would need to be
+implemented separately, as would some way of isolating static memory belonging
+to each partition but not the code. Because of these complications, this option
+has not been considered further at this time.
+
+--------------
+
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/tfm_psa_inter_process_communication.rst b/docs/design_docs/services/tfm_psa_inter_process_communication.rst
new file mode 100644
index 0000000..312d6ae
--- /dev/null
+++ b/docs/design_docs/services/tfm_psa_inter_process_communication.rst
@@ -0,0 +1,228 @@
+################################
+TF-M Inter-Process Communication
+################################
+
+:Authors: Ken Liu, Mingyang Sun
+:Organization: Arm Limited
+:Contact: ken.liu@arm.com, mingyang.sun@arm.com
+
+***********
+Terminology
+***********
+
+IPC - Inter-Process Communication
+
+For more terminology please check Reference_ document.
+
+***************
+Design Overview
+***************
+Components for implementing IPC:
+
+- SPM – for partition information and isolation actions
+- Core – for exception handling
+- Memory pool
+- Message manager
+- Thread
+- Synchronization objects
+- PSA API
+
+**********************
+Implementation Details
+**********************
+Listed modules are all internal modules except PSA API. Prototypes and
+definitions are not listed for internal modules in this document. For PSA
+API definitions, check them in PSA Firmware Framework specification in the
+reference chapter.
+
+SPM and Core
+============
+SPM manages Secure Partition information. Enhancements need to be done in SPM
+data structure for Secure Partition for IPC due to:
+
+- IPC model requires each Secure Partition has its own stack area.
+- Multiple services are holding in same Secure Partition and each service
+ has its own information like message queue, SID and priority.
+- Changed information related manifest items need to be changed, too.
+
+Modifications in Core:
+
+- More SVC calls need to be added into list since PSA API are implemented as
+ SVC calls in TF-M.
+- New PendSV handler for thread scheduling.
+- Arch-related context stacking and switching.
+
+Memory Pool
+===========
+Handles of connection and messages for Secure Partition needs to be allocated
+dynamically. A memory pool is provided in the system to handle dynamic
+allocation. Each memory pool item contains below information:
+
+- A list iterator to chain all of memory pool items.
+- An information member to record information like size and types.
+- The memory item body for caller usage.
+
+A memory area needs to be provided in SPM for the memory pool. It could be an
+array of memory areas defined in the linker script. Two chains are available to
+manage the items: free chain and used chain. And an LRU (Last recent used)
+mechanism is applied for fast seeking while item allocating and destroying.
+
+Message Manager
+===============
+Message Manager handles message creating, pushing, retrieving and destroy. A
+message contains below information:
+
+- Message sender and destination
+- Message status
+- IO vectors for service
+- 'psa_msg_t' for service
+
+A checking needs to be performed in SPM before creating a message to detect if
+a message with the same sender and destination is ongoing. This avoids repeat
+messages are available in the queue.
+
+Thread
+======
+Each Secure Partition has a thread as execution environment. Secure Partition
+is defined statically in TF-M manifest, which indicates that a number of
+threads are statically defined. Threads are chained in SPM and sorted with
+its priority, and there is an extra indicator point to first running thread
+with the highest priority. This helps fast seeking of running threads while
+the scheduler is switching threads.
+
+Thread context contains below information:
+
+- Priority
+- Status
+- Stack pointer
+- Stack pointer limitation
+- Entry
+- Parameter
+- Entry return value
+- Context
+- List iterator
+
+Thread API provides below functions:
+
+- Thread creating and destroying
+- Thread status retrieving and changing
+- Current thread retrieving
+- Thread context switching
+
+PendSV exception in TF-M core is the place thread context APIs been called.
+Before thread switching taking place, isolation status needs to be changed
+based on Secure Partition change and current isolation level – a thread is a
+member of partition which means thread switching caused a partition switching.
+
+Synchronization API
+===================
+A first synchronization object is an event. This could be applied into event
+waiting in the partition, and message response handling in IPC. The event
+object contains below members:
+
+- Owner thread who is waiting for this event
+- Event status (Ready or Not-Ready)
+- List iterator for synchronization objects management
+
+Event API Limitation: could be waited by one thread only.
+
+PSA API
+=======
+This chapter describes the PSA API in an implementation manner.
+
+- API type: could be Client API and Service Partition API
+- Block-able: Block-able API may block caller thread; Non-Block API does not
+ block caller thread.
+- Description: The functionality description and important comments.
+
+.. code-block:: c
+
+ uint32_t psa_framework_version(void);
+ uint32_t psa_version(uint32_t sid);
+
+- Client API
+- Non-Block API
+- These 2 functions are finally handled in SPM and return the framework version
+ or version to the caller.
+
+.. code-block:: c
+
+ psa_handle_t psa_connect(uint32_t sid, uint32_t version);
+ psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len);
+ void psa_close(psa_handle_t handle);
+
+- Client API
+- Block-able API
+- These 3 APIs are implemented in the same manner and just different
+ parameters. SPM converts each call into a corresponding message with a
+ parameter in the message body and pushes the message into service queue to
+ wait for the response. Scheduler switches to a specified thread (partition)
+ and makes Secure Partition to have chance retrieving and process message.
+ After a message response is returned to the caller, the waiting caller gets
+ to go and get the result.
+
+.. code-block:: c
+
+ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
+
+- Secure Partition API
+- Block-able API
+- This API blocks caller partition if there is no expected event for it. This
+ function is implemented based on event API.
+
+.. code-block:: c
+
+ void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
+ psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
+ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
+ void *buffer, size_t num_bytes);
+ size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,
+ size_t num_bytes);
+ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
+ const void *buffer, size_t num_bytes);
+ void psa_reply(psa_handle_t msg_handle, psa_status_t status);
+ void psa_clear(void);
+ void psa_eoi(psa_signal_t irq_signal);
+
+- Secure Partition API
+- Non-Block
+- These APIs do not take the initiative to change caller status. They process
+ data and return the processed data back to the caller.
+
+.. code-block:: c
+
+ void psa_notify(int32_t partition_id);
+
+- Secure Partition API
+- Non-Block
+- This API sets DOORBELL bit in destination partition's event. This API does
+ not take the initiative to change caller status.
+
+.. code-block:: c
+
+ void psa_panic(void);
+
+- Secure Partition API
+- Block-able API
+- This function will terminate execution within the calling Secure Partition
+ and will not return.
+
+*********
+Reference
+*********
+
+| `PSA Firmware Framework specification URL`_
+| `Slides includes IPC basic introduction URL`_
+| `IPC model implementation URL`_
+
+.. _PSA Firmware Framework specification URL:
+ https://www.arm.com/architecture/security-features/platform-security
+.. _Slides includes IPC basic introduction URL: https://connect.linaro.org/
+ resources/yvr18/sessions/yvr18-108/
+.. _IPC model implementation URL: https://www.youtube.com/watch?v=6wEFoq49qUw
+
+--------------
+
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/tfm_secure_partition_runtime_library.rst b/docs/design_docs/services/tfm_secure_partition_runtime_library.rst
new file mode 100644
index 0000000..6df1c28
--- /dev/null
+++ b/docs/design_docs/services/tfm_secure_partition_runtime_library.rst
@@ -0,0 +1,361 @@
+################################
+Secure Partition Runtime Library
+################################
+
+:Organization: Arm Limited
+:Contact: tf-m@lists.trustedfirmware.org
+
+**********
+Background
+**********
+Trusted Firmware - M (TF-M) uses a toolchain provided runtime library and
+supervisor calls to easily implement the PSA Firmware Framework (PSA FF) API.
+This working model works well under isolation level 1 since there are no data
+isolation requirements. While TF-M is evolving, this model is not suitable
+because:
+
+ - The high-level isolation requires isolating data but some toolchain library
+ interfaces have their own global data which cannot be shared between the
+ Secure Partitions.
+ - The toolchain libraries are designed without taking security as a core
+ design principle.
+
+A TF-M specific runtime library is needed for the following reasons:
+
+ - Easier evaluation or certification by security standards.
+ - Source code transparency.
+ - Sharing code to save ROM and RAM space for TF-M.
+
+PSA FF specification also describes the requirements of C runtime API for Secure
+Partitions.
+
+This runtime library is named the ``Secure Partition Runtime Library``, and the
+abbreviation is ``SPRTL``.
+
+****************
+Design Principal
+****************
+The following requirements are mandatory for SPRTL implementation:
+
+.. important::
+ - **CODE ONLY** - No read-write data should be introduced into runtime library
+ implementation.
+ - **Thread safe** - All functions are designed with thread-safe consideration.
+ These APIs access caller stack and caller provided memory only.
+ - **Isolation** - Runtime API code is set as executable and read-only in
+ higher isolation levels.
+ - **Security first** - SPRTL is designed for security and it may come with
+ some performance loss.
+
+API Categories
+==============
+Several known types of functions are included in SPRTL:
+
+ - C runtime API.
+ - RoT Service API.
+ - PSA Client and Service API.
+ - [Future expansion, to be detailed later] other secure API.
+
+Security Implementation Requirements
+------------------------------------
+If ``malloc/realloc/free`` are provided, they must obey additional requirements
+compared to the C standard: newly allocated memory must be initialized to
+ZERO, and freed memory must be wiped immediately in case the block contains
+sensitive data.
+
+The comparison API ('memcmp' e.g.), they should not return immediately when the
+fault case is detected. The implementation should execute in linear time based
+on input to avoid execution timing side channel attack.
+
+The pointer validation needs to be considered. In general, at least the
+'non-NULL' checking is mandatory. A detection for invalid pointer leads to a
+``psa_panic()``.
+
+The following section describes the first 3 API types and the implementation
+requirements.
+
+C Runtime API
+-------------
+PSA FF describes a small set of the C standard library. Part of toolchain
+library API can be used as default if these APIs meet the `Design Principal`_
+and `Security Implementation Requirements`_. The toolchain 'header' and 'types'
+can be reused to simplify the implementation.
+
+These APIs can take the toolchain provided version, or separately implemented
+in case there are extra requirements:
+
+.. note::
+ - 'memcpy()/memmove()/memset()'
+ - String API
+
+These APIs are proposed to be implemented with the security consideration
+mentioned in `Security Implementation Requirements`_:
+
+.. note::
+ - 'memcmp()'
+ - Other comparison API if referenced ('strcmp' e.g.).
+
+The following functions are optional, but if present, they must conform to
+additional `Security Implementation Requirements`_:
+
+.. note::
+ - 'malloc()/free()/realloc()'
+ - 'assert()/printf()'
+
+The following APIs are coupled with toolchain library much so applying toolchain
+library implementation is recommended:
+
+.. note::
+ - Division and modulo - arithmetic operations.
+ - Other low level or compiler specific functions (such as 'va_list').
+
+Besides the APIs mentioned above, the following runtime APIs are required for
+runtime APIs with private runtime context ('malloc' e.g.):
+
+.. note::
+ - '__sprtmain()' - partition entry runtime wrapper.
+
+RoT Service API
+---------------
+The description of RoT Service API in PSA FF:
+
+.. note::
+ Arm recommends that the RoT Service developer also defines an RoT Service API
+ and implementation to encapsulate the use of the IPC protocol, and improve the
+ usability of the service for client firmware.
+
+Part of the RoT Service API have proposed specifications, such as the PSA
+Cryptography API, PSA Storage API, and PSA Attestation API. It is suggested that
+the service developer create documents of their RoT Service API and make them
+publicly available.
+
+The RoT Service API has a large amount and it is the main part of SPRTL. This
+chapter describes the general implementation of the RoT Service API and the
+reason for putting them into SPRTL.
+
+In general, a client uses the PSA Client API to access a secure service.
+For example:
+
+.. code-block:: c
+
+ /* Example, not a real implementation */
+ caller_status_t psa_example_service(void)
+ {
+ ...
+ handle = psa_connect(SERVICE_SID, SERVICE_VERSION);
+ if (INVALID_HANDLE(handle)) {
+ return INVALID_RETURN;
+ }
+
+ status = psa_call(handle, type, invecs, inlen, outvecs, outlen);
+
+ psa_close(handle);
+
+ return TO_CALLER_STATUS(status);
+ }
+
+This example encapsulates the PSA Client API, and can be provided as a simpler
+and more generic API for clients to call. It is not possible to statically link
+this API to each Secure Partition because of the limited storage space. The
+ideal solution is to put it inside SPRTL and share it to all Secure Partitions.
+This would simplify the caller logic into this:
+
+.. code-block:: c
+
+ if (psa_example_service() != STATUS_SUCCESS) {
+ /* do something */
+ }
+
+This is the simplest case of encapsulating PSA Client API. If a RoT Service API
+is connect heavy, then, the encapsulation can be changed to include a connection
+handle inside a context data structure. This context data structure type is
+defined in RoT Service headers and the instance is allocated by API caller since
+API implementation does not have private data.
+
+.. note::
+ - Even the RoT Service APIs are provided in SPRTL for all clients, the SPM
+ performs the access check eventually and decides if the access to service
+ can be processed.
+ - For those RoT Service APIs only get called by a specific client, they can be
+ implemented inside the caller client, instead of putting it into SPRTL.
+
+PSA Client and Service API
+--------------------------
+Most of the PSA APIs can be called directly with supervisor calls. The only
+special function is ``psa_call``, because it has **6** parameters. This makes
+the supervisor call handler complex because it has to extract the parameters
+from the stack. The definition of psa_call is the following:
+
+.. code-block:: c
+
+ psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len);
+
+The parameters need to be packed to avoid passing parameters on the stack, and
+the supervisor call needs to unpack the parameters back to **6** for subsequent
+processing.
+
+Privileged Access Supporting
+============================
+Due to specified API (printf, e.g.) need to access privileged resources, TF-M
+Core needs to provide interface for the resources accessing. The permission
+checking must happen in Core while caller is calling these interface.
+
+Secure Partition Scratch Area
+=============================
+For the API needs partition specific private data, there needs to be a way to
+pass the partition specific data for the API. Use C language preprocessor to
+forward the existing prototype declaration can work, but it has the risks of
+breaking the build since this method needs compilers support ('-include' e.g.).
+Furthermore, no valid runtime tricks can work due to these limitations on
+M-profile architecture:
+
+.. note::
+ - We cannot apply the aligned mask on a stack address to get stack bottom
+ where the private data pointer stands. This is because aligned stack bottom
+ is not supported.
+ - We cannot read special registers such as 'PSPLIMIT' for retrieving the
+ private data pointer while executing in unprivileged mode.
+ - Furthermore, some earlier versions of the ARM architecture do not have
+ certain special-purpose registers ('PSPLIMIT' etc.).
+
+A system-provided scratch area is a precondition for implementing APIs that need
+to access private data (such as 'malloc'). The requirements for implementing
+such an area are:
+
+.. important::
+ - The area must be ``READ-ONLY`` for the running Secure Partition.
+ - The SPM must put the running Secure Partition's metadata into this area
+ while scheduling.
+
+With these requirements, the passed parameters can be retrieved by SPRTL easily
+with a read operation on the fixed memory address.
+
+Tooling Support on Partition Entry
+==================================
+PSA FF requires each Secure Partition to have an entry point. For example:
+
+.. code-block:: c
+
+ /* The entry point function must not return. */
+ void entry_point(void);
+
+Each partition has its own dedicated metadata for heap tracking and other
+runtime state. The metadata is designed to be saved at the read-write data area
+of a partition with a specific name. A generic entry point needs to be available
+to get partition metadata and do initialization before calling into the actual
+partition entry. This generic entry point is defined as '__sprtmain':
+
+.. code-block:: c
+
+ void __sprtmain(void)
+ {
+ /* Get current SP private data from scratch area */
+ struct sprt_meta_t *m = (struct sprt_meta_t *)tfm_sprt_scratch_data;
+
+ /* Potential heap init - check later chapter */
+ if (m->heap_size) {
+ m->heap_instance = tfm_sprt_heap_init(m->heap_sa, m->heap_sz);
+ }
+
+ /* Call thread entry 'entry_point' */
+ m->thread_entry();
+
+ /* SVC back to tell Core end this thread */
+ SVC(THREAD_EXIT);
+ }
+
+Since SPM is not aware of the '__sprtmain' in SPRTL, it just calls into the
+entry point listed in partition runtime data structure. And the partition writer
+may be not aware of running of '__sprtmain' as the generic wrapper entry,
+tooling support needs to happen to support this magic. Here is an example of
+partition manifest:
+
+.. code-block:: sh
+
+ {
+ "name": "TFM_SP_SERVICE",
+ "type": "PSA-ROT",
+ "priority": "NORMAL",
+ "entry_point": "tfm_service_entry",
+ "stack_size": "0x1800",
+ "heap_size": "0x1000",
+ ...
+ }
+
+Tooling would do manipulation to tell SPM the partition entry as '__sprtmain',
+and TF-M SPM would switch the activated metadata into the scratch area. Finally,
+the partition entry point gets called and run, tooling helps on the decoupling
+of SPM and SPRTL implementation. The pseudo code of a tooling result:
+
+.. code-block:: c
+
+ struct partition_t sp1 {
+ .name = "TFM_SP_SERVICE",
+ .type = PSA_ROT,
+ .priority = NORMAL,
+ .id = 0x00000100,
+ .entry_point = __sprtmain, /* Tell SPM entry is '__sprtmain' */
+ .metadata = { /* struct sprt_meta_t */
+ .heap_sa = sp1_heap_buf,
+ .heap_sz = sizeof(sp1_heap_buf),
+ .thread_entry = sp1_entry, /* Actual Partition Entry */
+ .heap_instance = NULL,
+ },
+ }
+
+Implementation
+==============
+The SPRTL C Runtime sources are put under:
+'$TFM_ROOT/secure_fw/partitions/lib/runtime/'
+
+The output of this folder is a static library named as 'libtfm_sprt.a'. The code
+of 'libtfm_sprt.a' is put into a dedicated section so that a hardware protected
+region can be applied to contain it.
+
+The RoT Service API are put under service interface folder. These APIs are
+marked with the same section attribute where 'libtfm_sprt.a' is put.
+
+The Formatting API - 'printf' and variants
+------------------------------------------
+The 'printf' and its variants need special parameters passing mechanism. To
+implement these APIs, the toolchain provided builtin macro 'va_list', 'va_start'
+and 'va_end' cannot be avoided. This is because of some scenarios such as when
+'stack canaries' are enabled, only the compiler knows the format of the 'canary'
+in order to extract the parameters correctly.
+
+To provide a simple implementation, the following requirements are defined for
+'printf':
+
+- Format keyword 'xXduscp' needs to be supported.
+- Take '%' as escape flag, '%%' shows a '%' in the formatted string.
+- To save heap usage, 32 bytes buffer in the stack for collecting formatted
+ string.
+- Flush string outputting due to: a) buffer full b) function ends.
+
+The interface for flushing can be a logging device.
+
+Function with Implied Parameters
+--------------------------------
+Take 'malloc' as an example. There is only one parameter for 'malloc' in
+the prototype. Heap management code is put in the SPRTL for sharing with caller
+partitions. The heap instance belongs to each partition, which means this
+instance needs to be passed into the heap management code as a parameter. For
+allocation API in heap management, it needs two parameters - 'size' and
+'instance', while for 'malloc' caller it needs a 'malloc' with one parameter
+'size' only. As mentioned in the upper chapter, this instance can be retrieved
+from the Secure Partition scratch area. The implementation can be:
+
+.. code-block:: c
+
+ void *malloc(size_t sz)
+ {
+ struct sprt_meta_t *m = (struct sprt_meta_t *)tfm_sprt_scratch_data;
+
+ return tfm_sprt_alloc(m->heap_instance, sz);
+ }
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/services/tfm_uniform_secure_service_signature.rst b/docs/design_docs/services/tfm_uniform_secure_service_signature.rst
new file mode 100644
index 0000000..28e3d8f
--- /dev/null
+++ b/docs/design_docs/services/tfm_uniform_secure_service_signature.rst
@@ -0,0 +1,113 @@
+################################
+Uniform Secure Service Signature
+################################
+
+:Author: Miklos Balint
+:Organization: Arm Limited
+:Contact: Miklos Balint <miklos.balint@arm.com>
+
+**********************************
+Declaring secure service interface
+**********************************
+
+The following alternative secure service signature is proposed as an
+amendment to existing implementation.
+
+Individual signatures - current method
+======================================
+
+A ``<service_name>_veneers.c`` file is created in the ``secure_fw/ns_callable``
+directory, that specifies the signature for each veneer function, and calls the
+secure function from the veneers. The respective
+``interface/include/<service_name>_veneers.h`` file with the veneer declarations
+have to be created and maintained manually.
+Note that at present TF-M framework limits the range of valid return values a
+secure service can provide, reserving a range for framework error codes.
+
+Uniform signatures - proposal
+=============================
+
+The proposal is to use a uniform signature for all the secure functions of the
+secure service. There are multiple advantages of this method:
+
+- TF-M Core can do a sanity check on the access rights of the veneer
+ parameters, and there is no need for the secure services to make these checks
+ individually. Please note that in the present implementation sanity check is
+ only fully supported for level 1 isolation.
+
+- The veneer declarations and implementations for the secure functions can be
+ generated automatically from a template (using the secure function list in the
+ secure service's manifest)
+
+The signature for such secure services would look like this:
+
+.. code-block:: c
+
+ psa_status_t secure_function_name(struct psa_invec *in_vec, size_t in_len,
+ struct psa_outvec *out_vec, size_t out_len);
+
+where
+
+Return value:
+-------------
+
+``psa_status_t`` is a status code whose values are described in PSA Firmware
+Framework (as in version 1.0-beta-0 chapter 4.3.3).
+
+Note:
+-----
+The return value limitations imposed by TF-M framework for proprietary
+secure service veneers would not apply to secure services using the uniform
+signature. This is analogous to how PSA Firmware Framework handles values
+returned by ``psa_reply()`` function.
+
+Arguments:
+----------
+
+.. code-block:: c
+
+ /**
+ * A read-only input memory region provided to a RoT Service.
+ */
+ typedef struct psa_invec {
+ const void *base; /*!< the start address of the memory buffer */
+ size_t len; /*!< the size in bytes */
+ } psa_invec;
+
+ /**
+ * A writable output memory region provided to a RoT Service.
+ */
+ typedef struct psa_outvec {
+ void *base; /*!< the start address of the memory buffer */
+ size_t len; /*!< the size in bytes */
+ } psa_outvec;
+
+ /**
+ * in_len: the number of input parameters, i.e. psa_invecs
+ * out_len: the number of output parameters, i.e. psa_outvecs
+ */
+
+The number of vectors that can be passed to a secure service is constrained:
+
+.. code-block:: c
+
+ in_len + out_len <= PSA_MAX_IOVEC
+
+The veneer function declarations and implementations are generated in the
+``interface/include/tfm_veneers.h`` and ``secure_fw\ns_callable\tfm_veneers.c``
+files respectively. The veneer functions are created with the name
+``tfm_<secure_function_name>_veneer``
+
+Services that implement the uniform signature do not need to manually fill
+the template veneer function to call ``TFM_CORE_SFN_REQUEST`` macro.
+
+*************
+Compatibility
+*************
+
+Note that the proposal is for the two types of services (those with proprietary
+signatures and those with uniform signatures) to co-exist, with the intention of
+eventually phasing out proprietary signatures in favour of the more robust,
+uniform signature.
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
\ No newline at end of file