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/booting/bl1.rst b/docs/design_docs/booting/bl1.rst
new file mode 100644
index 0000000..831d019
--- /dev/null
+++ b/docs/design_docs/booting/bl1.rst
@@ -0,0 +1,302 @@
+########################
+BL1 Immutable bootloader
+########################
+
+:Author: Raef Coles
+:Organization: Arm Limited
+:Contact: raef.coles@arm.com
+
+************
+Introduction
+************
+
+Some devices that use TF-M will require initial boot code that is stored in ROM.
+There are a variety of reasons that this might happen:
+
+- The device cannot access flash memory without a driver, so needs some setup
+ to be done before main images on flash can be booted.
+- The device has no on-chip secure flash, and therefore cannot otherwise
+ maintain a tamper-resistant root of trust.
+- The device has a security model that requires an immutable root of trust
+
+Henceforth any bootloader stored in ROM will be referred to as BL1, as it would
+necessarily be the first stage in the boot chain.
+
+TF-M provides a reference second-stage flash bootloader BL2, in order to allow
+easier integration. This bootloader implements all secure boot functionality
+needed to provide a secure chain of trust.
+
+A reference ROM bootloader BL1 has now being added with the same motivation -
+allowing easier integration of TF-M for platforms that do not have their own
+BL1 and require one.
+
+****************************
+BL1 Features and Motivations
+****************************
+
+The reference ROM bootloader provides the following features:
+
+- A split between code being stored in ROM and in other non-volatile memory.
+
+ - This can allow significant cost reduction in fixing bugs compared to
+ ROM-only bootloaders.
+
+- A secure boot mechanism that allows upgrading the next boot stage (which
+ would usually be BL2).
+
+ - This allows for the fixing of any bugs in the BL2 image.
+ - Alternately, this could allow the removal of BL2 in some devices that are
+ constrained in flash space but have ROM.
+
+- A post-quantum resistant asymmetric signature scheme for verifying the next
+ boot stage image.
+
+ - This can allow devices to be securely updated even if attacks
+ involving quantum computers become viable. This could extend the lifespans
+ of devices that might be deployed in the field for many years.
+
+- A mechanism for passing boot measurements to the TF-M runtime so that they
+ can be attested.
+- Tooling to create and sign images.
+- Fault Injection (FI) and Differential Power Analysis (DPA) mitigations.
+
+*********************************
+BL1_1 and BL1_2 split bootloaders
+*********************************
+
+BL1 is split into two distinct boot stages, BL1_1 which is stored in ROM and
+BL1_2 which is stored in other non-volatile storage. This would usually be
+either trusted or untrusted flash, but on platforms without flash memory can be
+OTP. As BL1_2 is verified against a hash stored in OTP, it is immutable after
+provisioning even if stored in mutable storage.
+
+Bugs in ROM bootloaders usually cannot be fixed once a device is provisioned /
+in the field, as ROM code is immutable the only option is fixing the bug in
+newly manufactured devices.
+
+However, it can be very expensive to change the ROM code of devices once
+manufacturing has begun, as it requires changes to the photolithography masks
+that are used to create the device. This cost varies depending on the complexity
+of the device and of the process node that it is being fabricated on, but can be
+large, both in engineering time and material/process costs.
+
+By placing the majority of the immutable bootloader in other storage, we can
+mitigate the costs associated with changing ROM code, as a new BL1_2 image can
+be used at provisioning time with minimal changeover cost. BL1_1 contains a
+minimal codebase responsible mainly for the verification of the BL1_2 image.
+
+The bootflow is as follows. For simplicity this assumes that the boot stage
+after BL1 is BL2, though this is not necessarily the case:
+
+1) BL1_1 begins executing in place from ROM
+2) BL1_1 copies BL1_2 into RAM
+3) BL1_1 verifies BL1_2 against the hash stored in OTP
+4) BL1_1 jumps to BL1_2, if the hash verification has succeeded
+5) BL1_2 copies the primary BL2 image from flash into RAM
+6) BL1_2 verifies the BL2 image using asymmetric cryptography
+7) If verification fails, BL1_2 repeats 5 and 6 with the secondary BL2 image
+8) BL1_2 jumps to BL2, if either image has successfully verified
+
+.. Note::
+ The BL1_2 image is not encrypted, so if it is placed in untrusted flash it
+ will be possible to read the data in the image.
+
+Some optimizations have been made specifically for the case where BL1_2 has been
+stored in OTP:
+
+OTP can be very expensive in terms of chip area, though new technologies like
+antifuse OTP decrease this cost. Because of this, the code size of BL1_2 has
+been minimized. Code-sharing has been configured so that BL1_2 can call
+functions stored in ROM. Care should be taken that OTP is sized such that it is
+possible to include versions of the functions used via code-sharing, in case the
+ROM functions contain bugs, though less space is needed than if all code is
+duplicated as it is assumed that most functions will not contain bugs.
+
+As OTP memory frequently has low performance, BL1_2 is copied into RAM before it
+it is executed. It also copies the next image stage into RAM before
+authenticating it, which allows the next stage to be stored in untrusted flash.
+This requires that the device have sufficient RAM to contain both the BL1_2
+image and the next stage image at the same time. Note that this is done even if
+BL1_2 is located in XIP-capable flash, as it both allows the use of untrusted
+flash and simplifies the image upgrade logic.
+
+.. Note::
+ BL1_2 enables TF-M to be used on devices that contain no secure flash, though
+ the ITS service will not be available. Other services that depend on ITS will
+ not be available without modification.
+
+*************************************
+Secure boot / Image upgrade mechanism
+*************************************
+
+BL1_2 verifies the authenticity of the next stage image via asymmetric
+cryptography, using a public key that is provisioned into OTP.
+
+BL1_2 implements a rollback protection counter in OTP, which is used to prevent
+the next stage image being downgraded to a less secure version.
+
+BL1_2 has two image slots, which allows image upgrades to be performed. The
+primary slot is always booted first, and then if verification of this fails
+(either due to an invalid signature or due to a version lower than the rollback
+protection counter) the secondary slot is then booted (subject to the same
+checks).
+
+BL1_2 contains no image upgrade logic, in order for OTA of the next stage image
+to be implemented, a later stage in the system must handle downloading new
+images and placing them in the required slot.
+
+********************************************
+Post-Quantum signature verification in BL1_2
+********************************************
+
+BL1_2 uses a post-quantum asymmetric signature scheme to verify the next stage.
+The scheme used is Leighton-Michaeli Signatures (henceforth LMS). LMS is
+standardised in `NIST SP800-208
+<https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf>`_
+and `IETF RFC8554. <https://datatracker.ietf.org/doc/html/rfc8554>`_
+
+LMS is a stateful-hash signature scheme, meaning that:
+
+ 1) It is constructed from a cryptographic hash function, in this case SHA256.
+
+ - This function can be accelerated by existing hardware accelerators, which
+ can make LMS verification relatively fast compared to other post-quantum
+ signature schemes that cannot be accelerated in hardware yet.
+
+ 2) Each private key can only be used to sign a certain number of images.
+
+ - BL1_2 uses the SHA256_H10 parameter set, meaning each key can sign 1024
+ images.
+
+The main downside, the limited amount of possible signatures, can be mitigated
+by limiting the amount of image upgrades that are done. As BL2 is often
+currently not upgradable, it is not anticipated that this limit will be
+problematic. If BL1 is being used to directly boot a TF-M/NS combined image, the
+limit is more likely to be problematic, and care should be taken to examine the
+likely update amount.
+
+LMS public keys are 32 bytes in size, and LMS signatures are 1912 bytes in size.
+The signature size is larger than some asymmetric schemes, though most devices
+should have enough space in flash to accommodate this.
+
+The main upside of LMS, aside from the security against attacks involving
+quantum computers, is that it is relatively simple to implement. The software
+implementation that is used by BL1 is ~3KiB in size, which is considerably
+smaller than the corresponding RSA implementation which is at least 6.5K. This
+simplicity of implementation is useful to avoid bugs.
+
+BL1 will use MbedTLS as the source for its implementation of LMS.
+
+.. Note::
+ As of the time of writing, the LMS code is still in the process of being
+ merged into MbedTLS, so BL1 currently does not support asymmetric
+ verification of the next boot stage. Currently, the next boot stage is
+ hash-locked, so cannot be upgraded.
+
+ The Github pull request for LMS can be found `here
+ <https://github.com/ARMmbed/mbedtls/pull/4826>`_
+
+*********************
+BL1 boot measurements
+*********************
+
+BL1 outputs boot measurements in the same format as BL2, utilising the same
+shared memory area. These measurements can then be included in the attestation
+token, allowing the attestation of the version of the boot stage after BL1.
+
+***********
+BL1 tooling
+***********
+
+Image signing scripts are provided for BL1_1 and BL1_2. While the script is
+named ``create_bl2_img.py``, it can be used for any next stage image.
+
+- ``bl1/bl1_1/scripts/create_bl1_2_img.py``
+- ``bl1/bl1_2/scripts/create_bl2_img.py``
+
+These sign (and encrypt in the case of ``create_bl2_img.py``) a given image file
+and append the required headers.
+
+**************************
+BL1 FI and DPA mitigations
+**************************
+
+BL1 reuses the FI countermeasures used in the TF-M runtime, which are found in
+``lib/fih/``.
+
+BL1 implements countermeasures against DPA, which are primarily targeted
+towards being able to handle cryptographic material without leaking its
+contents. The functions with these countermeasures are found in
+``bl1/bl1_1/shared_lib/util.c``
+
+``bl_secure_memeql`` tests if memory regions have the same value
+
+- It does not perform early exits to prevent timing attacks.
+- It compares chunks in random orders to prevent DPA trace correlation analysis
+- It inserts random delays to prevent DPA trace correlation analysis
+- It performs loop integrity checks
+- It uses FIH constructs
+
+``bl_secure_memcpy`` copies memory regions
+
+- It copies chunks in random orders to prevent DPA trace correlation analysis
+- It inserts random delays to prevent DPA trace correlation analysis
+- It performs loop integrity checks
+- It uses FIH constructs
+
+**************************
+Using BL1 on new platforms
+**************************
+
+New platforms must define the following macros in their ``region_defs.h``:
+
+- ``BL1_1_HEAP_SIZE``
+- ``BL1_1_STACK_SIZE``
+- ``BL1_2_HEAP_SIZE``
+- ``BL1_2_STACK_SIZE``
+- ``BL1_1_CODE_START``
+- ``BL1_1_CODE_LIMIT``
+- ``BL1_1_CODE_SIZE``
+- ``BL1_2_CODE_START``
+- ``BL1_2_CODE_LIMIT``
+- ``BL1_2_CODE_SIZE``
+- ``PROVISIONING_DATA_START``
+- ``PROVISIONING_DATA_LIMIT``
+- ``PROVISIONING_DATA_SIZE``
+
+The ``PROVISIONING_DATA_*`` defines are used to locate where the data to be
+provisioned into OTP can be found. These are required as the provisioning bundle
+needs to contain the entire BL1_2 image, usually >= 8KiB in size, which is too
+large to be placed in the static data area as is done for all other dummy
+provisioning data. On development platforms with reprogrammable ROM, this is
+often placed in unused ROM. On production platforms, this should be located in
+RAM and then filled with provisioning data. The format of the provisioning data
+that should be located in the ``PROVISIONING_DATA_*`` region can be found in
+``bl1/bl1_1/lib/provisioning.c`` in the struct
+``bl1_assembly_and_test_provisioning_data_t``
+
+If the platform is storing BL1_2 in flash, it must set
+``BL1_2_IMAGE_FLASH_OFFSET`` to the flash offset of the start of BL1_2.
+
+The platform must also implement the HAL functions defined in the following
+headers:
+
+- ``bl1/bl1_1/shared_lib/interface/trng.h``
+- ``bl1/bl1_1/shared_lib/interface/crypto.h``
+- ``bl1/bl1_1/shared_lib/interface/otp.h``
+
+If the platform integrates a CryptoCell-312, then it can reuse the existing
+implementation.
+
+***********
+BL1 Testing
+***********
+
+New tests have been written to test both the HAL implementation, and the
+integration of those functions for verifying images. These tests are stored in
+the ``tf-m-tests`` repository, under the ``test/bl1/`` directory, and further
+subdivided into BL1_1 and BL1_2 tests.
+
+--------------
+
+*Copyright (c) 2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/booting/index.rst b/docs/design_docs/booting/index.rst
new file mode 100644
index 0000000..7326868
--- /dev/null
+++ b/docs/design_docs/booting/index.rst
@@ -0,0 +1,8 @@
+.. toctree::
+ :maxdepth: 1
+
+ Secure Boot <tfm_secure_boot.rst>
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/booting/secure_boot_hw_key_integration.rst b/docs/design_docs/booting/secure_boot_hw_key_integration.rst
new file mode 100644
index 0000000..7d8afdd
--- /dev/null
+++ b/docs/design_docs/booting/secure_boot_hw_key_integration.rst
@@ -0,0 +1,165 @@
+HW crypto key integration in TF-M secure boot
+=============================================
+
+:Author: Tamas Ban
+:Organization: Arm Limited
+:Contact: Tamas Ban <tamas.ban@arm.com>
+
+Abstract
+--------
+
+`PSA Trusted Boot and Firmware Update <https://pages.arm.com/psa-resources-tbfu.html>`__
+specification requires the support of at least one immutable root of trust
+public key (ROTPK) for firmware verification. This can be stored using a locked
+on-chip flash memory, a secure-element or on-chip OTP memory. It also beneficial
+to be able to provision these keys during the factory life-cycle of the device
+independently from any software components. The current key handling solution
+in TF-M secure boot does not supports this key provisioning process. MCUBoot
+requires compile time built-in public key(s) for image verification. This
+limitation does not fit well with a scenario with multiple vendors where
+multiple MCU software components might be deployed by different vendors in
+different points in the life-cycle of the device and they do not want to share
+the keys in-advance for embedding in the bootloader code. The goal of this
+document to propose a solution to decouple MCUBoot from public key(s) and
+enable the independent deployment of ROTPK.
+
+Existing key handling solution
+------------------------------
+
+MCUBoot code contains a compile-time built-in key array which can store any
+number of key(s) for firmware verification: ``bl2/ext/mcuboot/keys.c``. These
+public key(s) must be available when MCUBoot image is built. There is a script
+``bl2/ext/mcuboot/scipt/imgtool.py`` which can generate a new key pair, and
+extract the public key part in the expected ASN.1 format and encode it as C
+structure. The script is also capable of signing the image with the private key.
+In order to identify and validate the corresponding public key during image
+verification the hash of the public key is appended to the image manifest area
+(TLV encoded metadata). During image verification the bootloader retrieves the
+hash of the public key from the manifest area and compare against the on-the-fly
+calculated hash value of the built-in public keys. An exact match identifies and
+validates the public key which must be used for image verification.
+
+Current memory layout::
+
+ |----------------------|
+ | |
+ | MCUBoot code |
+ | |
+ | Full public key |
+ | |
+ |----------------------|
+ | |
+ | Image |
+ | |
+ |----------------------|
+ | Image Manifest(TLV) |
+ | |
+ | Hash of public key |
+ |----------------------|
+ | |
+ | Rest of memory |
+ | |
+
+Requirements
+------------
+
+- Multiple independent vendor scenario must be supported, when more than one
+ ROTPK is provisioned to the device.
+- The corresponding public key for image verification must be identifiable and
+ verifiable.
+- Key identity must be immutable and anchored to the device itself.
+- Key(s) can be provisioned independently from bootloader.
+
+Design proposal
+---------------
+HW key(s) might stored in OTP memory which is an expensive resource, so
+storing a large key (such as RSA) is inefficient. Therefore, it is assumed that
+only the hash of the ROTPK will be stored in the HW. If only the hash of the
+public key is stored in the HW then the whole public key must be transfered to
+the device, because it must be available during image verification. This
+transfer can be done in the same way as how the hash of the key is transfered
+to the device with the current solution. A new TLV type (TLV_KEY) can be
+introduced to carry the whole public key. The corresponding public key will be
+appended to the image itself in the manifest area. It has the drawback that the
+image will be bigger, but it is assumed that the additional cost of the bigger
+image (extra flash area + power for download) is less than the cost of the OTP
+area.
+
+The verification flow:
+
+ - Look up the TLV_KEY field to get the public key.
+ - Calculates its hash(SHA256) value.
+ - Get the hash of ROTPK from the platform layer (stored in HW)
+ - Compare the two hash values, if they match then the key can be used to
+ validate the image. In case of failure consider the images as unauthenticated.
+
+Proposed memory layout::
+
+ |----------------------|
+ | |
+ | MCUBoot code |
+ | |
+ | NO PUBLIC KEY |
+ | |
+ |----------------------|
+ | |
+ | Image |
+ | |
+ |----------------------|
+ | Image Manifest(TLV) |
+ | |
+ | Full public key |
+ |----------------------|
+ | |
+ | |
+ | Rest of memory |
+ | |
+ | |
+ |----------------------|
+ | Immutable memory |
+ | |
+ | Hash of public key |
+ |----------------------|
+ | |
+
+Platform support
+----------------
+
+A new platform API used by the bootloader must be introduced to retrieve the
+image corresponding hash of ROTPK:
+
+``enum tfm_plat_err_t tfm_plat_get_rotpk_hash(uint8_t image_id,
+uint8_t *rotpk_hash, uint32_t *rotpk_hash_size);``
+
+The mapping between image identity and public key can be hard-code in the
+platform layer. This simplifies the validation of the public key, because no
+look-up would be needed. It is assumed that the memory area of the ROTPK hash is
+not directly accessible, therefore a buffer is allocated by the caller to store
+the hash there.
+
+Compile time configurability
+----------------------------
+
+The solution must be compile time configurable in order to be able to switch
+between built-in key(s) and HW key(s) support, and also due to backwards
+compatibility.
+
+Tooling
+-------
+
+``bl2/ext/mcuboot/scipt/imgtool.py`` will be modified to include the whole
+public key to the TLV area (instead of the hash).
+
+Table to compare the current and proposed solution::
+
+ |---------|-----------------------|-------------------|--------------------|
+ | |Key format in manifest |Key in MCUBoot code| Key in HW |
+ |---------|-----------------------|-------------------|--------------------|
+ |Proposed | Full public key | No key embedded | Hash of public key |
+ |---------|-----------------------|-------------------|--------------------|
+ |Current | Hash of public key | Full public key | No key in HW |
+ |---------|-----------------------|-------------------|--------------------|
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/booting/secure_boot_rollback_protection.rst b/docs/design_docs/booting/secure_boot_rollback_protection.rst
new file mode 100644
index 0000000..8fc66f4
--- /dev/null
+++ b/docs/design_docs/booting/secure_boot_rollback_protection.rst
@@ -0,0 +1,202 @@
+#######################################
+Rollback protection in TF-M secure boot
+#######################################
+
+:Author: Tamas Ban
+:Organization: Arm Limited
+:Contact: Tamas Ban <tamas.ban@arm.com>
+
+Anti-rollback protection
+========================
+The goal of anti-rollback protection is to prevent downgrading of the device to
+an older version of its software, which has been deprecated due to security
+concerns.
+
+Elements of software upgrade
+============================
+During a software upgrade the following entities are involved:
+
+ - Boot loader
+ - Manifest data: Metadata of the software image: size, version, hash,
+ signature, etc.
+ - Software image: binary data, elf, etc.
+
+Validation of new image
+=======================
+Boot loader is responsible to authenticate the new image according to the
+required policies and decide whether the new image is fulfilling all the
+requirements. Boot loader verifies the image integrity (hash calculation) and
+the origination (signature validation), and might verify other requirements as
+well. If the new image is successfully authenticated then the boot loader is in
+charge to do the necessary steps (load to execute address, etc.) to enable the
+new image to be executed. During the validation process the image and the
+manifest data is checked.
+
+Manifest format in MCUBoot
+==========================
+MCUBoot has a custom manifest format, which is composed of two parts:
+
+ - Image header: Prepended to the beginning of the image.
+ It is integrity protected:
+ - TLV section: Appended to the end of the image. It is not integrity protected:
+
+ - Hash of public key, hash of image, signature of image
+
+.. code-block:: c
+
+ struct image_header {
+ uint32_t ih_magic;
+ uint32_t ih_load_addr;
+ uint16_t ih_hdr_size;
+ uint16_t _pad1;
+ uint32_t ih_img_size;
+ uint32_t ih_flags;
+ struct image_version ih_ver;
+ uint32_t _pad2;
+ };
+
+Security counter
+================
+The aim of a security counter is to have an independent (from the image version)
+counter in the image manifest to ensure anti-rollback protection. During
+software release the value of this counter must be increased if a security flaw
+was fixed in the current version. Later when this image is installed on the
+device then it is not allowed to go back to earlier versions. It is beneficial
+to handle this counter independently from image main version number:
+
+ - It does not need to increase with each software release
+ - It makes it possible to do software downgrade to some extent: if the security
+ counter has the same value in the older image then it is accepted.
+ - If the boot loader verifies multiple images then these can be handled
+ independently.
+
+However, as an alternative solution the image version number also could serve
+as the security counter of the image. Even the version number itself could be
+checked during the anti-rollback verification or the value of the security
+counter could be derived from the image main version. It is the responsibility
+of the software issuer to define which policy to apply.
+
+Implementation of security counter
+==================================
+The value of the security counter is a security critical data. Any change in
+its value has a security implication. Therefore it must be in the integrity
+protected part of the image manifest. Because the image header is almost fully
+utilized (few unused fields) and the change of image header structure could
+lead to compatibility issues between boot loader and runtime software, it is
+proposed to extend the integrity protection to some part of the TLV section.
+One of the unused fields in the image header can be used to store the size of
+the integrity protected area of the TLV section. This is necessary to know how
+to calculate properly the image hash and signature. With this extension of the
+integrity protected area other attributes that require integrity protection
+can easily be added to the image manifest.
+
+Trusted non-volatile (NV) counters
+==================================
+The Trusted Base System Architecture (TBSA-M) defines non-volatile (NV) counters
+or version counters as a counter with the following properties:
+
+ - It must only be possible to increment a version counter through a Trusted
+ access.
+ - It must only be possible to increment a version counter. It must not be
+ possible to decrement it.
+ - When a version counter reaches its maximum value, it must not roll over,
+ and no further changes must be possible.
+ - A version counter must be non-volatile, and the stored value must survive
+ a power down period up to the lifetime of the device.
+
+Trusted non-volatile counters can be used to store the value of security
+counters per updatable software image. Ideally all independently updatable
+software images should have a separate security counter. In current TF-M
+implementation the BL2 is not updatable and the secure and non-secure images
+are updated together as a single binary. Therefore, one counter is enough to
+implement rollback protection. In future the secure and non-secure binaries
+will be handled independently; at that time the introduction of a second
+counter will be necessary.
+
+Currently the NV counters can be manipulated through the interface described
+in ``tfm_plat_nv_counters.h``.
+
+NV counters and anti-rollback protection
+========================================
+Trusted non-volatile counters might not be supported by a hardware platform.
+In this case anti-rollback protection might still be feasible.
+
+The device threat model needs to consider the following aspects:
+
+ - What is the trust level of the boot loader towards the active software
+
+ - If the boot loader cannot protect the anti-rollback mechanism from the
+ secure image then the following threat is unmitigated: The content of the
+ memory area which holds the active image could be replaced with a valid but
+ an older version of the software with software only attack, i.e.: remote
+ code execution.
+ - If the boot loader does not trust the loaded image at all then security
+ counter must have a copy in NV counter area.
+
+ - Another aspect to consider is where the active image is stored
+
+ - Trusted memory: i.e. on-chip flash (eFlash). The threat that a malicious
+ actor can modify the content of trusted memory with HW attack is out of
+ scope for the current implementation. It is assumed that if an active image
+ and related manifest data is stored in trusted memory then the included
+ security counter cannot be compromised.
+ - Untrusted memory: i.e. external (off-chip) storage, where malicious actor
+ can physically access it so it is possible to modify its content, therefore
+ the value of included security counter is unreliable.
+
+If the active image is stored in untrusted storage and it is feasible to modify
+its content (i.e. replace the whole image to an older version including
+corresponding manifest) then the value of security counter must be copied to
+the NV counter area. During software validation the boot loader must compare
+the new image's security counters against the security counter stored in
+non-volatile counters.
+
+If the active image is stored in trusted memory and boot loader trusts in the
+active software then it is not mandatory to store the security counter to
+non-volatile counter area. During software validation the boot loader is
+allowed to compare the new image's security counters against active image's
+security counter.
+
+The evaluation of trusted and untrusted memory must be done per target platform
+during threat modelling.
+
+For the most robust implementation the following principles should be applied:
+
+ - Always use NV counters for storing security counter value if supported by
+ the hardware.
+ - Each software stage must not be able to decrease their corresponding NV
+ counter.
+
+Boot flow with anti-rollback protection
+=======================================
+During software upgrade as part of the image validation process the new and
+active image security counters must be compared. The new image can be accepted
+if its security counter has a greater or equal value than the active image
+security counter. From where to extract the active image security counter it
+can be platform dependent. It might read out directly from active image
+manifest data (only if it is in trusted memory) or the corresponding
+non-volatile counter is read.
+
+If non-volatile counters are used to save security counters then their value
+must be updated:
+
+ - If the boot loader does not support to revert previous images (just
+ overwrites the previously active image with the new one) in case of faulty
+ update then the non-volatile counter can be updated to be equal with the
+ new image security counter after successful authentication of the new image.
+ - If revert is supported then non-volatile counter can be updated just after
+ a test run of the new software when its health check is done. Just in case
+ of successful health check can the counter updated to avoid the prevention
+ of the revert. This might require a secondary restart of the device.
+
+Tool support
+============
+There is a Python script, ``imgtool.py`` which is used to prepare the new image
+for upgrade (add header, sign the image, append TLV section). This script must
+be modified to get an additional command line argument which serves as security
+counter. The security counter must be included in the integrity protected part
+of the TLV section.
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/booting/tfm_secure_boot.rst b/docs/design_docs/booting/tfm_secure_boot.rst
new file mode 100644
index 0000000..df3bbaf
--- /dev/null
+++ b/docs/design_docs/booting/tfm_secure_boot.rst
@@ -0,0 +1,826 @@
+###########
+Secure boot
+###########
+
+.. toctree::
+ :maxdepth: 1
+
+ BL1 Immutable bootloader <bl1.rst>
+ Rollback Protection <secure_boot_rollback_protection.rst>
+ HW Key integration <secure_boot_hw_key_integration.rst>
+
+For secure devices it is security critical to enforce firmware authenticity to
+protect against execution of malicious software. This is implemented by building
+a trust chain where each step in the execution chain authenticates the next
+step before execution. The chain of trust in based on a "Root of Trust" which
+is implemented using asymmetric cryptography. The Root of Trust is a combination
+of an immutable bootloader and a public key (ROTPK).
+
+.. Warning::
+ In order to implement a proper chain of trust functionality, it is
+ mandatory that the first stage bootloader and ROTPK is stored in an
+ **immutable** way. To achieve this the bootloader code must be stored and
+ executed from ROM or such part of flash memory which supports write
+ protection. ROTPK can be stored in a one-time-programmable (OTP) memory. If
+ the SoC has a built-in BL1 (immutable) bootloader and the immutability of
+ TF-M secure boot code is not guaranteed then TF-M secure boot code must be
+ authenticated by BL1 bootloader before execution. If immutability of root
+ of trust (first stage bootloader + ROTPK) is not ensured then there is a
+ risk that the secure boot process could be bypassed, which could lead to
+ arbitrary code execution on the device. Current TF-M secure boot code is
+ intended to be a second stage bootloader, therefore it requires
+ authentication before execution. If TF-M secure boot code is used as a first
+ stage bootloader then it must be stored according to the above requirements.
+
+*******************************
+Second stage bootloader in TF-M
+*******************************
+By default, the MCUboot project from
+`GitHub <https://github.com/mcu-tools/mcuboot>`__ is used as the secure
+bootloader in TF-M. The repository is going to be automatically downloaded by
+CMake. The version downloaded can be controlled by the ``MCUBOOT_VERSION``
+CMake variable. If you wish to use a locally downloaded copy, the CMake variable
+``MCUBOOT_PATH`` can be set to its location. This document contains information
+about how MCUboot has been integrated to TF-M. For further information about
+MCUboot design please refer to the `MCUBoot homepage <https://www.mcuboot.com/>`__.
+
+Bootloader is started when CPU is released from reset. It runs in secure mode.
+It authenticates the firmware image by hash (SHA-256) and digital signature
+(RSA-3072) validation. Public key, that the checks happens against, can be built
+into the bootloader image or can be provisioned to the SoC during manufacturing.
+Metadata of the image is delivered together with the image itself in a header
+and trailer section. In case of successful authentication, bootloader passes
+execution to the secure image. Execution never returns to bootloader until
+next reset.
+
+A default RSA key pair is stored in the repository, public key is in ``keys.c``
+and private key is in ``root-RSA-3072.pem``.
+
+.. Danger::
+ DO NOT use the default keys in a production code, they are exclusively
+ for testing!
+
+The private key must be stored in a safe place outside of the repository.
+``imgtool.py`` (found in the ``scripts`` directory in the MCUBoot repository,
+or installed through the pip package manager) can be used to generate new key
+pairs.
+
+The bootloader can handle the secure and non-secure images independently
+(multiple image boot) or together (single image boot). In case of multiple image
+boot they are signed independently with different keys and they can be updated
+separately. In case of single image boot the secure and non-secure image is
+handled as a single blob, therefore they must be contiguous in the device
+memory. In this case they are signed together and also they can be updated only
+together. In order to have the same artefacts at the end of the build regardless
+of how the images are handled (independently or together) the images are always
+concatenated. In case of single image boot they are concatenated first and then
+signed. In case of multiple image boot they are separately signed first and then
+concatenated. Preparation of payload is done by Python scripts:
+``bl2/ext/mcuboot/scripts/``. At the end of a successful build the signed TF-M
+payload can be found in: ``<build_dir>/bin/tfm_s_ns_signed.bin``
+
+*********************
+Integration with TF-M
+*********************
+MCUBoot assumes a predefined memory layout which is described below (applicable
+for AN521). It is mandatory to define the primary slot and the secondary slot
+partitions, but their size and location can be changed::
+
+ - 0x0000_0000 - 0x0007_FFFF: BL2 bootloader - MCUBoot
+ - 0x0008_0000 - 0x000F_FFFF: Primary slot : Single binary blob:
+ Secure + Non-Secure image;
+ Primary memory partition
+ - 0x0008_0000 - 0x0008_03FF: Common image header
+ - 0x0008_0400 - 0x0008_xxxx: Secure image
+ - 0x0008_xxxx - 0x0010_03FF: Padding (with 0xFF)
+ - 0x0010_0400 - 0x0010_xxxx: Non-secure image
+ - 0x0010_xxxx - 0x0010_xxxx: Hash value(SHA256), RSA signature and other
+ metadata of combined image
+
+ - 0x0018_0000 - 0x0027_FFFF: Secondary slot : Secure + Non-Secure image;
+ Secondary memory partition, structured
+ identically to the primary slot
+ - 0x0028_0000 - 0x0037_FFFF: Scratch area, only used during image
+ swapping
+
+Multiple image boot requires a slightly different layout::
+
+ - 0x0000_0000 - 0x0007_FFFF: BL2 bootloader - MCUBoot
+ - 0x0008_0000 - 0x000F_FFFF: Primary slot : Secure image
+ - 0x0008_0000 - 0x0008_03FF: Secure image header
+ - 0x0008_0400 - 0x000x_xxxx: Secure image
+ - 0x000x_xxxx - 0x000x_xxxx: Hash value(SHA256), RSA signature and other
+ metadata of secure image
+
+ - 0x0010_0000 - 0x0017_FFFF: Primary slot : Non-secure image
+ - 0x0010_0000 - 0x0010_03FF: Non-secure image header
+ - 0x0010_0400 - 0x001x_xxxx: Non-secure image
+ - 0x001x_xxxx - 0x001x_xxxx: Hash value(SHA256), RSA signature and other
+ metadata of non-secure image
+
+ - 0x0018_0000 - 0x001F_FFFF: Secondary slot : Secure image
+ - 0x0020_0000 - 0x0027_FFFF: Secondary slot : Non-secure image
+
+ - 0x0028_0000 - 0x002F_FFFF: Scratch area, only used during image
+ swapping, used for secure and non-secure
+ image as well
+
+**************************
+Firmware upgrade operation
+**************************
+MCUBoot handles only the firmware authenticity check after start-up and the
+firmware switch part of the firmware update process. Downloading the new version
+of the firmware is out-of-scope for MCUBoot. MCUBoot supports three different
+ways to switch to the new firmware and it is assumed that firmware images are
+executed-in-place (XIP). The default behaviour is the overwrite-based image
+upgrade. In this case the active firmware is always executed from the primary
+slot and the secondary slot is a staging area for new images. Before executing
+the new firmware image, the content of the primary slot must be overwritten with
+the content of the secondary slot (the new firmware image). The second option is
+the image swapping strategy when the content of the two memory slots must be
+physically swapped. This needs the scratch area to be defined in the memory
+layout. The third option is the direct execute-in-place version, which
+eliminates the complexity of image swapping and its administration. Active image
+can be executed from either memory slot, but new firmware must be linked to the
+address space of the proper (currently inactive) memory slot.
+
+Overwrite operation
+===================
+Active image is stored in the primary slot, and this image is started always by
+the bootloader. Therefore images must be linked to the primary slot. If the
+bootloader finds a valid image in the secondary slot, which is marked for
+upgrade, then the content of the primary slot will be simply overwritten with
+the content of the secondary slot, before starting the new image from the
+primary slot. After the content of the primary slot has been successfully
+overwritten, the header and trailer of the new image in the secondary slot is
+erased to prevent the triggering of another unnecessary image upgrade after a
+restart. The overwrite operation is fail-safe and resistant to power-cut
+failures. For more details please refer to the MCUBoot
+`documentation <https://www.mcuboot.com/mcuboot/design.html>`__.
+
+Swapping operation
+==================
+This operation can be set with the ``MCUBOOT_UPGRADE_STRATEGY`` compile time
+switch (see `Build time configuration`_). With swapping image upgrade strategy
+the active image is also stored in the primary slot and it will always be
+started by the bootloader. If the bootloader finds a valid image in the
+secondary slot, which is marked for upgrade, then contents of the primary slot
+and the secondary slot will be swapped, before starting the new image from the
+primary slot. Scratch area is used as a temporary storage place during image
+swapping. Update mark from the secondary slot is removed when the swapping is
+successful. The boot loader can revert the swapping as a fall-back mechanism to
+recover the previous working firmware version after a faulty update. The swap
+operation is fail-safe and resistant to power-cut failures. For more details
+please refer to the MCUBoot
+`documentation <https://www.mcuboot.com/mcuboot/design.html>`__.
+
+.. Note::
+
+ After a successful image upgrade the firmware can mark itself as "OK" at
+ runtime by setting the image_ok flag in the flash. When this happens, the
+ swap is made "permanent" and MCUBoot will then still choose to run it
+ during the next boot. Currently TF-M does not set the image_ok flag,
+ therefore the bootloader will always perform a "revert" (swap the images
+ back) during the next boot.
+
+Direct execute-in-place operation
+=================================
+This operation can be set with the ``MCUBOOT_UPGRADE_STRATEGY`` compile time
+switch (see `Build time configuration`_). When enabling direct-xip operation
+then the active image flag is moved between slots during firmware upgrade. If
+firmware is executed-in-place (XIP), then two firmware images must be generated.
+One of them is linked to be executed from the primary slot memory region and the
+other from the secondary slot. The firmware upgrade client, which downloads the
+new image, must be aware, which slot hosts the active firmware and which acts as
+a staging area and it is responsible for downloading the proper firmware image.
+At boot time MCUBoot inspects the version number in the image header and passes
+execution to the newer firmware version. New image must be marked for upgrade
+which is automatically done by Python scripts at compile time. Image
+verification is done the same way in all operational modes. If new image fails
+during authentication then MCUBoot erases the memory slot and starts the other
+image, after successful authentication.
+
+To select which slot the image is to be executed from, set
+``MCUBOOT_EXECUTION_SLOT`` to the desired index. It is suggested that you create
+two build directories when building images using this mode, as intermediate
+dependencies cannot be reused due to changes in the flash layout.
+
+.. Note::
+
+ Only single image boot is supported with direct-xip upgrade mode.
+
+RAM Loading firmware upgrade
+============================
+Musca-S supports an image upgrade mode that is separate to the other (overwrite,
+swapping and dirext-xip) modes. This is the ``RAM load`` mode (please refer
+to the table below). Like the direct-xip mode, this selects the newest image
+by reading the image version numbers in the image headers, but instead of
+executing it in place, the newest image is copied to RAM for execution. The load
+address, the location in RAM where the image is copied to, is stored in the
+image header.
+
+Summary of different modes for image upgrade
+============================================
+Different implementations of the image upgrade operation (whether through
+overwriting, swapping, direct-xip or loading into RAM and executing from
+there) are supported by the platforms. The table below shows which of these
+modes are supported by which platforms:
+
++---------------------+-----------------+----------------------------------------------------------+
+| | Without BL2 [1]_| With BL2 [2]_ |
++=====================+=================+===============+==========+================+==============+
+| | XIP | XIP | XIP | XIP | Not XIP |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| | | Overwrite [3]_| Swap [4]_| direct-xip [5]_| RAM load [6]_|
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN521 | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN519 | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| FVP_SSE300_MPS3 | No | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| Corstone-310 FVP | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| LPC55S69 | Yes | Yes | No | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| Musca-B1 | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| Musca-S1 | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN524 | Yes | No | No | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN547 | No | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN552 | No | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| PSoC64 | Yes | No | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| STM_DISCO_L562QE | No | Yes | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| STM_NUCLEO_L552ZE_Q | No | Yes | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| nRF9160 DK | Yes | Yes | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| nRF5340 DK | Yes | Yes | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| BL5340 DVK | Yes | Yes | Yes | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| RSS | No | No | No | No | Yes |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+
+.. [1] To disable BL2, please set the ``BL2`` cmake option to ``OFF``
+
+.. [2] BL2 is enabled by default
+
+.. [3] The image executes in-place (XIP) and is in Overwrite mode for image
+ update by default
+
+.. [4] To enable XIP Swap mode, assign the "SWAP_USING_SCRATCH" or
+ "SWAP_USING_MOVE" string to the ``MCUBOOT_UPGRADE_STRATEGY``
+ configuration variable in the build configuration file, or include this
+ macro definition in the command line
+
+.. [5] To enable direct-xip, assign the "DIRECT_XIP" string to the
+ ``MCUBOOT_UPGRADE_STRATEGY`` configuration variable in the build
+ configuration file, or include this macro definition in the command line
+
+.. [6] To enable RAM load, assign the "RAM_LOAD" string to the
+ ``MCUBOOT_UPGRADE_STRATEGY`` configuration variable in the build
+ configuration file, or include this macro definition in the command line
+
+*******************
+Multiple image boot
+*******************
+It is possible to update the firmware images independently to support the
+scenario when secure and non-secure images are provided by different vendors.
+Multiple image boot is supported only together with the overwrite and swap
+firmware upgrade modes.
+
+It is possible to describe the dependencies of the images on each other in
+order to avoid a faulty upgrade when incompatible versions would be installed.
+These dependencies are part of the image manifest area.
+The dependencies are composed from two parts:
+
+ - **Image identifier:** The number of the image which the current image (whose
+ manifest area contains the dependency entry) depends on. The image identifier
+ starts from 0.
+
+ - **Minimum version:** The minimum version of other image must be present on
+ the device by the end of the upgrade (both images might be updated at the
+ same time).
+
+Dependencies can be added to the images at compile time with the following
+compile time switches:
+
+ - ``MCUBOOT_S_IMAGE_MIN_VER`` It is added to the non-secure image and specifies the
+ minimum required version of the secure image.
+ - ``MCUBOOT_NS_IMAGE_MIN_VER`` It is added to the secure image and specifies the
+ minimum required version of the non-secure image.
+
+Example of how to provide the secure image minimum version::
+
+ cmake -DTFM_PLATFORM=arm/musca_b1 -DMCUBOOT_S_IMAGE_MIN_VER=1.2.3+4 ..
+
+********************
+Signature algorithms
+********************
+MbedTLS library is used to sign the images. The list of supported signing
+algorithms:
+
+ - `RSA-2048`
+ - `RSA-3072`: default
+
+Example keys stored in:
+
+ - ``root-RSA-2048.pem`` : Used to sign single image (S+NS) or secure image
+ in case of multiple image boot
+ - ``root-RSA-2048_1.pem`` : Used to sign non-secure image in case of multiple
+ image boot
+ - ``root-RSA-3072.pem`` : Used to sign single image (S+NS) or secure image
+ in case of multiple image boot
+ - ``root-RSA-3072_1.pem`` : Used to sign non-secure image in case of multiple
+ image boot
+
+************************
+Build time configuration
+************************
+MCUBoot related compile time switches can be set by cmake variables.
+
+- BL2 (default: True):
+ - **True:** TF-M built together with bootloader. MCUBoot is executed after
+ reset and it authenticates TF-M and starts secure code.
+ - **False:** TF-M built without bootloader. Secure image linked to the
+ beginning of the device memory and executed after reset. If it is false
+ then using any of the further compile time switches is invalid.
+- MCUBOOT_UPGRADE_STRATEGY (default: "OVERWRITE_ONLY"):
+ - **"OVERWRITE_ONLY":** Default firmware upgrade operation with overwrite.
+ - **"SWAP_USING_SCRATCH":** Activate swapping firmware upgrade operation
+ with a scratch area in flash
+ - **"SWAP_USING_MOVE":** Activate swapping firmware upgrade operation
+ without a scratch area in flash
+ - **"DIRECT_XIP":** Activate direct execute-in-place firmware upgrade
+ operation.
+ - **"RAM_LOAD":** Activate RAM loading firmware upgrade operation, where
+ the latest image is copied to RAM and runs from there instead of being
+ executed in-place.
+- MCUBOOT_SIGNATURE_TYPE (default: RSA):
+ - **RSA:** Image is signed with RSA algorithm
+- MCUBOOT_SIGNATURE_KEY_LEN (default: 3072):
+ - **2048:** Image is signed with 2048 bit key.
+ - **3072:** Image is signed with 3072 bit key.
+- MCUBOOT_IMAGE_NUMBER (default: 2):
+ - **1:** Single image boot, secure and non-secure images are signed and
+ updated together.
+ - **2:** Multiple image boot, secure and non-secure images are signed and
+ updatable independently.
+- MCUBOOT_HW_KEY (default: True):
+ - **True:** The hash of public key is provisioned to the SoC and the image
+ manifest contains the whole public key (imgtool uses
+ ``--public_key_format=full``). MCUBoot validates the key before using it
+ for firmware authentication, it calculates the hash of public key from the
+ manifest and compare against the retrieved key-hash from the hardware.
+ This way MCUBoot is independent from the public key(s). Key(s) can be
+ provisioned any time and by different parties.
+ - **False:** The whole public key is embedded to the bootloader code and the
+ image manifest contains only the hash of the public key (imgtool uses
+ ``--public_key_format=hash``). MCUBoot validates the key before using it
+ for firmware authentication, it calculates the hash of built-in public key
+ and compare against the retrieved key-hash from the image manifest. After
+ this the bootloader can verify that the image was signed with a private
+ key that corresponds to the retrieved key-hash (it can have more public
+ keys embedded in and it may have to look for the matching one). All the
+ public key(s) must be known at MCUBoot build time.
+- MCUBOOT_LOG_LEVEL:
+ Can be used to configure the level of logging in MCUBoot. The possible
+ values are the following:
+
+ - **OFF**
+ - **ERROR**
+ - **WARNING**
+ - **INFO**
+ - **DEBUG**
+
+ The logging in MCUBoot can be disabled and thus the code size can be reduced
+ by setting it to ``OFF``. Its value depends on the build type. If the build
+ type is ``Debug`` then default value is ``INFO``. In case of different kinds
+ of ``Release`` builds the default value is ``OFF``. The default value can
+ be overridden through the command line or in the CMake GUI regardless of the
+ build type.
+- MCUBOOT_ENC_IMAGES (default: False):
+ - **True:** Adds encrypted image support in the source and encrypts the
+ resulting image using the ``enc-rsa2048-pub.pem`` key found in the MCUBoot
+ repository.
+ - **False:** Doesn't add encrypted image support and doesn't encrypt the
+ image.
+
+ .. Note::
+ The decryption takes place during the upgrade process, when the images
+ are being moved between the slots. This means that boards that don't
+ already have an image on them with MCUBoot that has been compiled with
+ ``MCUBOOT_ENCRYPT_RSA`` enabled need special treatment. In order to load
+ an encrypted image to such boards, an upgrade needs to be executed. This
+ can be done by using MCUBoot, putting an image in the secondary image
+ area, and setting ``MCUBOOT_ENCRYPT_RSA`` to ``ON``. When using the
+ ``OVERWRITE_ONLY`` upgrade strategy, this is enough. When using
+ ``SWAP_USING_SCRATCH`` or ``SWAP_USING_MOVE``, an image is needed in
+ the primary image area as well, to trigger the update.
+
+ .. Danger::
+ DO NOT use the ``enc-rsa2048-pub.pem`` key in production code, it is
+ exclusively for testing!
+
+Image versioning
+================
+An image version number is written to its header by one of the Python scripts,
+and this number is used by the bootloader when the direct execute-in-place or
+the RAM loading mode is enabled. It is also used in case of multiple image boot
+when the bootloader checks the image dependencies if any have been added to the
+images.
+
+The version number of the image (single image boot) can manually be passed in
+through the command line in the cmake configuration step::
+
+ cmake -DTFM_PLATFORM=arm/musca_b1 -DIMAGE_VERSION_S=1.2.3+4 ..
+
+Alternatively, the version number can be less specific (e.g 1, 1.2, or 1.2.3),
+where the missing numbers are automatically set to zero. The image version
+number argument is optional, and if it is left out, then the version numbers of
+the image(s) being built in the same directory will automatically change. In
+this case, the last component (the build number) automatically increments from
+the previous one: 0.0.0+1 -> 0.0.0+2, for as many times as the build is re-ran,
+**until a number is explicitly provided**. If automatic versioning is in place
+and then an image version number is provided for the first time, the new number
+will take precedence and be used instead. All subsequent image versions are
+then set to the last number that has been specified, and the build number would
+stop incrementing. Any new version numbers that are provided will overwrite
+the previous one: 0.0.0+1 -> 0.0.0+2. Note: To re-apply automatic image
+versioning, please start a clean build without specifying the image version
+number at all. In case of multiple image boot there are separate compile time
+switches for both images to provide their version: ``IMAGE_VERSION_S`` and
+``IMAGE_VERSION_NS``. These must be used instead of ``IMAGE_VERSION_S``.
+
+Security counter
+================
+Each signed image contains a security counter in its manifest. It is used by the
+bootloader and its aim is to have an independent (from the image version)
+counter to ensure rollback protection by comparing the new image's security
+counter against the original (currently active) image's security counter during
+the image upgrade process. It is added to the manifest (to the TLV area that is
+appended to the end of the image) by one of the Python scripts when signing the
+image. The value of the security counter is security critical data and it is in
+the integrity protected part of the image. The last valid security counter
+should always be stored in a non-volatile and trusted component of the device
+and its value should always be increased if a security flaw was fixed in the
+current image version. The value of the security counter (single image boot) can
+be specified at build time in the cmake configuration step::
+
+ cmake -DTFM_PLATFORM=arm/musca_b1 -DSECURITY_COUNTER_S=42 ../
+
+The security counter can be independent from the image version, but not
+necessarily. Alternatively, if it is not specified at build time with the
+``SECURITY_COUNTER`` option the Python script will automatically generate it
+from the image version number (not including the build number) and this value
+will be added to the signed image. In case of multiple image boot there are
+separate compile time switches for both images to provide their security counter
+value: ``SECURITY_COUNTER_S`` and ``SECURITY_COUNTER_NS``. These must be used
+instead of ``SECURITY_COUNTER_S``. If these are not defined then the security
+counter values will be derived from the corresponding image version similar to
+the single image boot.
+
+***************************
+Signing the images manually
+***************************
+Normally the build system handles the signing (computing hash over the image
+and security critical manifest data and then signing the hash) of the firmware
+images. However, the images also can be signed manually by using the ``imgtool``
+Python program which is located in the MCUboot repository in the ``scripts``
+folder or can be installed with the pip package manager.
+Issue the ``python3 imgtool.py sign --help`` command in the directory for more
+information about the mandatory and optional arguments. The tool takes an image
+in binary or Intel Hex format and adds a header and trailer that MCUBoot is
+expecting. In case of single image boot after a successful build the
+``tfm_s_ns.bin`` build artifact (contains the concatenated secure and non-secure
+images) must be passed to the script and in case of multiple image boot the
+``tfm_s.bin`` and ``tfm_ns.bin`` binaries can be passed to prepare the signed
+images.
+
+Signing the secure image manually in case of multiple image boot
+================================================================
+
+::
+
+ python3 bl2/ext/mcuboot/scripts/imgtool.py sign \
+ --layout <build_dir>/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.c.obj \
+ -k <tfm_dir>/bl2/ext/mcuboot/root-RSA-3072.pem \
+ --public-key-format full \
+ --align 1 \
+ -v 1.2.3+4 \
+ -d "(1,1.2.3+0)" \
+ -s 42 \
+ -H 0x400 \
+ <build_dir>/bin/tfm_s.bin \
+ <build_dir>/bin/tfm_s_signed.bin
+
+************************
+Testing firmware upgrade
+************************
+As downloading the new firmware image is out of scope for MCUBoot, the update
+process is started from a state where the original and the new image are already
+programmed to the appropriate memory slots. To generate the original and a new
+firmware package, TF-M is built twice with different build configurations.
+
+Overwriting firmware upgrade
+============================
+Run TF-M build twice with ``MCUBOOT_IMAGE_NUMBER`` set to "1" in both cases
+(single image boot), but with two different build configurations: default and
+regression. Save the artifacts between builds, because second run can overwrite
+original binaries. Download default build to the primary slot and regression
+build to the secondary slot.
+
+Executing firmware upgrade on FVP_MPS2_AEMv8M
+---------------------------------------------
+.. code-block:: bash
+
+ <ARM_DS_PATH>/sw/models/bin/FVP_MPS2_AEMv8M \
+ --parameter fvp_mps2.platform_type=2 \
+ --parameter cpu0.baseline=0 \
+ --parameter cpu0.INITVTOR_S=0x10000000 \
+ --parameter cpu0.semihosting-enable=0 \
+ --parameter fvp_mps2.DISABLE_GATING=0 \
+ --parameter fvp_mps2.telnetterminal0.start_telnet=1 \
+ --parameter fvp_mps2.telnetterminal1.start_telnet=0 \
+ --parameter fvp_mps2.telnetterminal2.start_telnet=0 \
+ --parameter fvp_mps2.telnetterminal0.quiet=0 \
+ --parameter fvp_mps2.telnetterminal1.quiet=1 \
+ --parameter fvp_mps2.telnetterminal2.quiet=1 \
+ --application cpu0=<build_dir>/bin/bl2.axf \
+ --data cpu0=<default_build_dir>/bin/tfm_s_ns_signed.bin@0x10080000 \
+ --data cpu0=<regresssion_build_dir>/bin/tfm_s_ns_signed.bin@0x10180000
+
+Executing firmware upgrade on SSE 200 FPGA on MPS2 board
+--------------------------------------------------------
+
+::
+
+ TITLE: Versatile Express Images Configuration File
+ [IMAGES]
+ TOTALIMAGES: 3 ;Number of Images (Max: 32)
+ IMAGE0ADDRESS: 0x00000000
+ IMAGE0FILE: \Software\bl2.axf ; BL2 bootloader
+ IMAGE1ADDRESS: 0x10080000
+ IMAGE1FILE: \Software\tfm_sig1.bin ; TF-M default test binary blob
+ IMAGE2ADDRESS: 0x10180000
+ IMAGE2FILE: \Software\tfm_sig2.bin ; TF-M regression test binary blob
+
+The following message will be shown in case of successful firmware upgrade:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Swap type: test
+ [INF] Image upgrade secondary slot -> primary slot
+ [INF] Erasing the primary slot
+ [INF] Copying the secondary slot to the primary slot: 0x100000 bytes
+ [INF] Bootloader chainload address offset: 0x80000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_PS_TEST_2XXX)...
+ ...
+
+To update the secure and non-secure images separately (multiple image boot),
+set the ``MCUBOOT_IMAGE_NUMBER`` switch to "2" (this is the default
+configuration value) and follow the same instructions as in case of single image
+boot.
+
+Executing multiple firmware upgrades on SSE 200 FPGA on MPS2 board
+------------------------------------------------------------------
+
+::
+
+ TITLE: Versatile Express Images Configuration File
+ [IMAGES]
+ TOTALIMAGES: 4 ;Number of Images (Max: 32)
+ IMAGE0ADDRESS: 0x00000000
+ IMAGE0FILE: \Software\bl2.axf ; BL2 bootloader
+ IMAGE1ADDRESS: 0x10080000
+ IMAGE1FILE: \Software\tfm_sign.bin ; TF-M default test binary blob
+ IMAGE2ADDRESS: 0x10180000
+ IMAGE2FILE: \Software\tfm_ss1.bin ; TF-M regression test secure (signed) image
+ IMAGE3ADDRESS: 0x10200000
+ IMAGE3FILE: \Software\tfm_nss1.bin ; TF-M regression test non-secure (signed) image
+
+Note that both the concatenated binary blob (the images are signed separately
+and then concatenated) and the separate signed images can be downloaded to the
+device because on this platform (AN521) both the primary slots and the secondary
+slots are contiguous areas in the Flash (see `Integration with TF-M`_). The
+following message will be shown in case of successful firmware upgrades:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Swap type: test
+ [INF] Swap type: test
+ [INF] Image upgrade secondary slot -> primary slot
+ [INF] Erasing the primary slot
+ [INF] Copying the secondary slot to the primary slot: 0x80000 bytes
+ [INF] Image upgrade secondary slot -> primary slot
+ [INF] Erasing the primary slot
+ [INF] Copying the secondary slot to the primary slot: 0x80000 bytes
+ [INF] Bootloader chainload address offset: 0x80000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+ TFM level is: 1
+ [Sec Thread] Jumping to non-secure code...
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_PS_TEST_2XXX)...
+ ...
+
+Swapping firmware upgrade
+=============================
+Follow the same instructions and platform related configurations as in case of
+overwriting build including these changes:
+
+- Set the ``MCUBOOT_UPGRADE_STRATEGY`` compile time switch to "SWAP"
+ before build.
+- Set the ``MCUBOOT_IMAGE_NUMBER`` compile time switch to "1" (single image
+ boot) or "2" (multiple image boot) before build.
+
+During single image boot the following message will be shown in case of
+successful firmware upgrade, ``Swap type: test`` indicates that images were
+swapped:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Image 0: magic= good, copy_done=0x3, image_ok=0x3
+ [INF] Scratch: magic= bad, copy_done=0x0, image_ok=0x2
+ [INF] Boot source: primary slot
+ [INF] Swap type: test
+ [INF] Bootloader chainload address offset: 0x80000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_PS_TEST_2XXX)...
+ ...
+
+Direct execute-in-place firmware upgrade
+========================================
+Follow the same instructions and platform related configurations as in case of
+overwriting build including these changes:
+
+- Set the ``MCUBOOT_UPGRADE_STRATEGY`` compile time switch to "DIRECT_XIP"
+ before build.
+- set ``MCUBOOT_EXECUTION_SLOT`` to ``1`` in the regression build dir.
+- Make sure the image version number was increased between the two build runs
+ either by specifying it manually or by checking in the build log that it was
+ incremented automatically.
+
+Executing firmware upgrade on FVP_MPS2_AEMv8M
+---------------------------------------------
+
+.. code-block:: bash
+
+ <ARM_DS_PATH>/sw/models/bin/FVP_MPS2_AEMv8M \
+ --parameter fvp_mps2.platform_type=2 \
+ --parameter cpu0.baseline=0 \
+ --parameter cpu0.INITVTOR_S=0x10000000 \
+ --parameter cpu0.semihosting-enable=0 \
+ --parameter fvp_mps2.DISABLE_GATING=0 \
+ --parameter fvp_mps2.telnetterminal0.start_telnet=1 \
+ --parameter fvp_mps2.telnetterminal1.start_telnet=0 \
+ --parameter fvp_mps2.telnetterminal2.start_telnet=0 \
+ --parameter fvp_mps2.telnetterminal0.quiet=0 \
+ --parameter fvp_mps2.telnetterminal1.quiet=1 \
+ --parameter fvp_mps2.telnetterminal2.quiet=1 \
+ --application cpu0=<build_dir>/bin/bl2.axf \
+ --data cpu0=<default_build_dir>/bin/tfm_s_ns_signed.bin@0x10080000 \
+ --data cpu0=<regresssion_build_dir>/bin/tfm_s_ns_signed.bin@0x10180000
+
+Executing firmware upgrade on SSE 200 FPGA on MPS2 board
+--------------------------------------------------------
+
+::
+
+ TITLE: Versatile Express Images Configuration File
+ [IMAGES]
+ TOTALIMAGES: 3 ;Number of Images (Max: 32)
+ IMAGE0ADDRESS: 0x00000000
+ IMAGE0FILE: \Software\bl2.axf ; BL2 bootloader
+ IMAGE1ADDRESS: 0x10080000
+ IMAGE1FILE: \Software\tfm_sign.bin ; TF-M default test binary blob
+ IMAGE2ADDRESS: 0x10180000
+ IMAGE2FILE: \Software\tfm_sig1.bin ; TF-M regression test binary blob
+
+Executing firmware upgrade on Musca-B1 and Musca-S1 boards
+----------------------------------------------------------
+After the two images have been built, they can be concatenated to create the
+combined image using ``srec_cat``:
+
+- Linux::
+
+ srec_cat bin/bl2.bin -Binary -offset 0xA000000 tfm_sign.bin -Binary -offset 0xA020000 tfm_sign_1.bin -Binary -offset 0xA100000 -o tfm.hex -Intel
+
+- Windows::
+
+ srec_cat.exe bin\bl2.bin -Binary -offset 0xA000000 tfm_sign.bin -Binary -offset 0xA020000 tfm_sign_1.bin -Binary -offset 0xA100000 -o tfm.hex -Intel
+
+The following message will be shown in case of successful firmware upgrade,
+notice that image with higher version number (``version=1.2.3.5``) is executed:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Image 0: version=1.2.3.4, magic= good, image_ok=0x3
+ [INF] Image 1: version=1.2.3.5, magic= good, image_ok=0x3
+ [INF] Booting image from the secondary slot
+ [INF] Bootloader chainload address offset: 0xa0000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_PS_TEST_2XXX)...
+ ...
+
+Executing firmware upgrade on CoreLink SSE-200 Subsystem for MPS3 (AN524)
+-------------------------------------------------------------------------
+
+::
+
+ TITLE: Arm MPS3 FPGA prototyping board Images Configuration File
+
+ [IMAGES]
+ TOTALIMAGES: 3 ;Number of Images (Max: 32)
+
+ IMAGE0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
+ IMAGE0ADDRESS: 0x00000000
+ IMAGE0FILE: \SOFTWARE\bl2.bin ;BL2 bootloader
+ IMAGE1UPDATE: AUTO
+ IMAGE1ADDRESS: 0x00040000
+ IMAGE1FILE: \SOFTWARE\tfm_sig0.bin ;TF-M example application binary blob
+ IMAGE2UPDATE: AUTO
+ IMAGE2ADDRESS: 0x000C0000
+ IMAGE2FILE: \SOFTWARE\tfm_sig1.bin ;TF-M regression test binary blob
+
+RAM loading firmware upgrade
+============================
+To enable RAM loading, please set ``MCUBOOT_UPGRADE_STRATEGY`` to "RAM_LOAD"
+(either in the configuration file or through the command line), and then specify
+a destination load address in RAM where the image can be copied to and executed
+from. The ``S_IMAGE_LOAD_ADDRESS`` macro must be specified in the target
+dependent files, and if multiple image boot is enabled then
+``NS_IMAGE_LOAD_ADDRESS`` must also be defined. For example with Musca-S, its
+``flash_layout.h`` file in the ``platform`` folder should include ``#define
+S_IMAGE_LOAD_ADDRESS #0xA0020000``
+
+Executing firmware upgrade on Musca-S board
+--------------------------------------------
+After two images have been built, they can be concatenated to create the
+combined image using ``srec_cat``:
+
+- Linux::
+
+ srec_cat bin/bl2.bin -Binary -offset 0xA000000 tfm_sign_old.bin -Binary -offset 0xA020000 tfm_sign_new.bin -Binary -offset 0xA100000 -o tfm.hex -Intel
+
+- Windows::
+
+ srec_cat.exe bin\bl2.bin -Binary -offset 0xA000000 tfm_sign_old.bin -Binary -offset 0xA020000 tfm_sign_new.bin -Binary -offset 0xA100000 -o tfm.hex -Intel
+
+The following message will be shown in case of successful firmware upgrade when,
+RAM loading is enabled, notice that image with higher version number
+(``version=0.0.0.2``) is executed:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Image 0: version=0.0.0.1, magic= good, image_ok=0x3
+ [INF] Image 1: version=0.0.0.2, magic= good, image_ok=0x3
+ [INF] Image has been copied from the secondary slot in flash to SRAM address 0xA0020000
+ [INF] Booting image from SRAM at address 0xA0020000
+ [INF] Bootloader chainload address offset: 0x20000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+--------------
+
+****************************************
+Integration with Firmware Update service
+****************************************
+The shim layer of the Firmware Update partition calls the APIs in
+bootutil_misc.c to control the image status.
+
+- Call ``boot_set_pending_multi()`` to make the image as a candidate image for
+ booting.
+- Call ``boot_set_confirmed_multi()`` to make the image as a permanent image.
+
+.. Note::
+ Currently, in direct-xip mode and ram-load mode, TF-M cannot get the
+ information of which slot contains the running image from the bootloader.
+ So the Firmware Update partition cannot decide where to write the new
+ image. As a result, the firmware update service is not supported in
+ direct-xip mode and ram-load mode.
+
+*Copyright (c) 2018-2022, Arm Limited. All rights reserved.*