|
| 1 | +.. _bootloader: |
| 2 | + |
| 3 | +Immutable bootloader |
| 4 | +#################### |
| 5 | + |
| 6 | +The bootloader sample implements an immutable first stage bootloader that has the capability to verify and boot a second stage bootloader. |
| 7 | +If the second stage bootloader is upgradable, it can reside in one of two slots. |
| 8 | +In this case, the sample chooses the second stage bootloader with the highest version number. |
| 9 | + |
| 10 | +See :ref:`ug_bootloader` for more information about the full bootloader chain. |
| 11 | +For information about creating a second stage bootloader, see :doc:`mcuboot:index`. |
| 12 | + |
| 13 | +Overview |
| 14 | +******** |
| 15 | + |
| 16 | +The bootloader sample provides a simple root of trust (RoT) as well as support for an upgradable second stage bootloader. |
| 17 | + |
| 18 | +This is accomplished by the following steps: |
| 19 | + |
| 20 | +1. Lock the flash. |
| 21 | + To enable the RoT, the bootloader sample locks the flash that contains the sample bootloader and its configuration. |
| 22 | + Locking is done using the hardware that is available on the given architecture. |
| 23 | + For details on locking, see the :ref:`fprotect_readme` driver. |
| 24 | + |
| 25 | +#. Select the next stage in the boot chain. |
| 26 | + The next stage in the boot chain can be another bootloader or the application. |
| 27 | + When the bootloader sample is enabled and MCUboot is used as second stage bootloader, there are two slots in which the second stage bootloader can reside. |
| 28 | + The second stage bootloader in each slot has a version number associated with it, and the bootloader sample selects the second stage bootloader that has the highest version number. |
| 29 | + |
| 30 | +#. Verify the next stage in the boot chain. |
| 31 | + After selecting the image to be booted next, the bootloader sample verifies its validity using one of the provisioned public keys hashes. |
| 32 | + The image for the next boot stage has a set of metadata associated with it. |
| 33 | + This metadata contains the full public key corresponding to the private key that was used to sign the firmware. |
| 34 | + The bootloader sample checks the public key against a set of provisioned keys. |
| 35 | + Note that to save space, only the hashes of the provisioned keys are stored, and only the hashes of the keys are compared. |
| 36 | + If the public key in the metadata matches one of the provisioned public key hashes, the image is considered valid. |
| 37 | + If the public key does not match any of the provisioned hashes, validation fails. |
| 38 | + |
| 39 | +#. Boot the next stage in the boot chain. |
| 40 | + After verifying the next boot stage, the bootloader sample uninitializes all peripherals that it used and boots the next boot stage. |
| 41 | + |
| 42 | +#. Share the cryptographic library over ABI. |
| 43 | + The bootloader sample does not contain any flash writing code. |
| 44 | + Therefore, it is safe to share some of its functionality through an Application Binary Interface (ABI, see :ref:`doc_fw_info_abi`). |
| 45 | + For more information, see :file:`bl_crypto.h`. |
| 46 | + |
| 47 | + |
| 48 | +Flash layout |
| 49 | +============ |
| 50 | + |
| 51 | +The flash layout is defined by :file:`samples/bootloader/pm.yml`. |
| 52 | + |
| 53 | +The bootloader sample defines four main areas: |
| 54 | + |
| 55 | +1. **B0** - Contains the bootloader sample. |
| 56 | +#. **Provision** - Stores the provisioned data. |
| 57 | +#. **S0** - One of two potential storage areas for the second stage bootloader. |
| 58 | +#. **S1** - One of two potential storage areas for the second stage bootloader. |
| 59 | + |
| 60 | +Provisioning |
| 61 | +============ |
| 62 | + |
| 63 | +The public key hashes are not compiled in with the source code of the bootloader sample. |
| 64 | +Instead, they are stored in a separate memory region through a process called *provisioning*. |
| 65 | + |
| 66 | +By default, the bootloader sample will automatically generate and provision public keys for the specified private key. |
| 67 | +To facilitate the manufacturing process of a device with the bootloader sample, it is possible to decouple this process and program the sample HEX file and the HEX file containing the public key hashes separately. |
| 68 | +If you choose to do so, use the Python scripts in ``scripts\bootloader`` to create and provision the keys manually. |
| 69 | + |
| 70 | + |
| 71 | +Requirements |
| 72 | +************ |
| 73 | + |
| 74 | +* One of the following development boards: |
| 75 | + |
| 76 | + * nRF9160 DK board (PCA10090) |
| 77 | + * nRF52840 Development Kit board (PCA10056) |
| 78 | + * nRF52 Development Kit board (PCA10040) |
| 79 | + * nRF51 Development Kit board (PCA10028) |
| 80 | + |
| 81 | +.. _bootloader_build_and_run: |
| 82 | + |
| 83 | +Building and running |
| 84 | +******************** |
| 85 | + |
| 86 | +The source code of the sample can be found under :file:`samples/bootloader/` in the |NCS| folder structure. |
| 87 | + |
| 88 | +The most common use case for the bootloader sample is to be included as a child image in a multi-image build, rather than being built stand-alone. |
| 89 | +Complete the following steps to add the bootloader sample as child image to your application: |
| 90 | + |
| 91 | +1. Create a private key in PEM format. |
| 92 | + To do so, run the following command, which stores your private key in a file name ``priv.pem`` in the current folder:: |
| 93 | + |
| 94 | + openssl ecparam -name prime256v1 -genkey -noout -out priv.pem |
| 95 | + |
| 96 | + OpenSSL is installed with GIT, so it should be available in your GIT bash. |
| 97 | + See `openSSL`_ for more information. |
| 98 | + |
| 99 | + .. note:: |
| 100 | + This step is optional for testing the bootloader chain. |
| 101 | + If you do not provide your own keys, debug keys are created automatically. |
| 102 | + However, you should never go into production with an application that is not protected by secure keys. |
| 103 | + |
| 104 | +#. Run ``menuconfig`` on your application to enable Secure Boot: |
| 105 | + |
| 106 | + a. Select **Project** > **Configure nRF Connect SDK project**. |
| 107 | + #. Go to **Modules** > **Nordic nRF Connect** and select **Use Secure Bootloader** to enable :option:`CONFIG_SECURE_BOOT`. |
| 108 | + #. Under **Private key PEM file** (:option:`CONFIG_SB_SIGNING_KEY_FILE`), enter the path to the private key that you created. |
| 109 | + If you choose to run the sample with default debug keys, you can skip this step. |
| 110 | + |
| 111 | + There are additional configuration options that you can modify, but it is not recommended to do so. |
| 112 | + The default settings are suitable for most use cases. |
| 113 | + |
| 114 | + .. note:: |
| 115 | + If you need more flexibility with signing, or if you do not want the build system to handle your private key, choose :option:`CONFIG_SB_SIGNING_CUSTOM`. |
| 116 | + This option allows you to define the signing command. |
| 117 | + In this case, you must also specify :option:`CONFIG_SB_SIGNING_COMMAND` and :option:`CONFIG_SB_SIGNING_PUBLIC_KEY`. |
| 118 | + |
| 119 | + #. Click **Configure**. |
| 120 | + |
| 121 | +#. Select **Build** > **Build Solution** to compile your application. |
| 122 | + The build process creates two images, one for the bootloader and one for the application, and merges them together. |
| 123 | +#. Select **Build** > **Build and Run** to program the resulting image to your device. |
| 124 | + |
| 125 | + |
| 126 | +Testing |
| 127 | +======= |
| 128 | + |
| 129 | +To test the bootloader sample, add it to any other sample and build and program that sample it as described above. |
| 130 | +Then test it by performing the following steps: |
| 131 | + |
| 132 | +#. |connect_terminal| |
| 133 | +#. Reset the board. |
| 134 | +#. Observe that the kit prints the following information:: |
| 135 | + |
| 136 | + Attempting to boot from address 0x8000. |
| 137 | + |
| 138 | + Verifying signature against key 0. |
| 139 | + |
| 140 | + Signature verified. |
| 141 | + |
| 142 | + Booting (0x8000). |
| 143 | + |
| 144 | +Dependencies |
| 145 | +************ |
| 146 | + |
| 147 | +This sample uses the following |NCS| libraries: |
| 148 | + |
| 149 | +* :ref:`partition_manager` |
| 150 | +* :ref:`doc_fw_info` |
| 151 | +* :ref:`fprotect_readme` |
| 152 | +* ``include/bl_validation.h`` |
| 153 | +* ``include/bl_crypto.h`` |
| 154 | +* ``subsys/bootloader/include/provision.h`` |
| 155 | + |
| 156 | +The sample also uses drivers from nrfx. |
0 commit comments