|
| 1 | +.. _protectedmem_periphconf_sample: |
| 2 | + |
| 3 | +Protected Memory with PERIPHCONF Partition |
| 4 | +########################################## |
| 5 | + |
| 6 | +.. contents:: |
| 7 | + :local: |
| 8 | + :depth: 2 |
| 9 | + |
| 10 | +This sample demonstrates how to protect the ``periphconf_partition`` using UICR.PROTECTEDMEM. The sample shows that when protected memory is modified, the integrity check fails on the next boot, causing IronSide SE to boot a secondary firmware instead of the main application. |
| 11 | + |
| 12 | +Requirements |
| 13 | +************ |
| 14 | + |
| 15 | +The sample supports the following development kit: |
| 16 | + |
| 17 | +.. table-from-sample-yaml:: |
| 18 | + |
| 19 | +Overview |
| 20 | +******** |
| 21 | + |
| 22 | +This sample demonstrates: |
| 23 | + |
| 24 | +* How to configure UICR.PROTECTEDMEM to protect a memory region |
| 25 | +* How to relocate the ``periphconf_partition`` using a device tree overlay to be placed right after ``cpuapp_boot_partition`` |
| 26 | +* How to configure the PROTECTEDMEM size in Kconfig to cover both ``cpuapp_boot_partition`` and ``periphconf_partition`` |
| 27 | +* How to configure a secondary firmware that boots when PROTECTEDMEM integrity check fails |
| 28 | +* How the protected memory region prevents unauthorized modifications by causing the secondary firmware to boot when integrity is violated |
| 29 | + |
| 30 | +The sample works as follows: |
| 31 | + |
| 32 | +1. The application writes a test pattern to the protected memory region |
| 33 | +2. The application then reboots |
| 34 | +3. On the next boot, the IronSide SE performs an integrity check of the protected memory region |
| 35 | +4. If the integrity check fails (because the memory was modified), IronSide SE automatically boots the secondary firmware instead of the main application |
| 36 | +5. The secondary firmware prints a message indicating that the PROTECTEDMEM integrity check failed, demonstrating that unauthorized modifications are detected and prevented |
| 37 | + |
| 38 | +Building and running |
| 39 | +********************* |
| 40 | + |
| 41 | +.. |sample path| replace:: :file:`samples/ironside_se/protectedmem_periphconf` |
| 42 | + |
| 43 | +.. include:: /includes/build_and_run_ns.txt |
| 44 | + |
| 45 | +To build the sample, run the following command: |
| 46 | + |
| 47 | +.. code-block:: console |
| 48 | +
|
| 49 | + west build -b <board> samples/ironside_se/protectedmem_periphconf |
| 50 | +
|
| 51 | +To program the sample on the device, run the following command: |
| 52 | + |
| 53 | +.. code-block:: console |
| 54 | +
|
| 55 | + west flash |
| 56 | +
|
| 57 | +Testing |
| 58 | +******* |
| 59 | + |
| 60 | +After programming the sample to your development kit, complete the following steps to test it: |
| 61 | + |
| 62 | +1. |connect_terminal| |
| 63 | +#. Reset the kit. |
| 64 | +#. Observe the console output: |
| 65 | + |
| 66 | +When you run the sample, you should see: |
| 67 | + |
| 68 | +.. code-block:: console |
| 69 | +
|
| 70 | + [00:00:00.123,456] === Protected Memory Demo === |
| 71 | + [00:00:00.123,457] periphconf_partition address: 0x0e040000 |
| 72 | + [00:00:00.123,458] periphconf_partition size: 0x2000 bytes |
| 73 | + [00:00:00.123,459] Last 16-byte aligned area start: 0x0e041ff0 |
| 74 | + [00:00:00.123,460] Test write address (last 4 bytes): 0x0e041ffc |
| 75 | + [00:00:00.123,461] Current value at protected address: 0xffffffff |
| 76 | + [00:00:00.123,462] |
| 77 | + [00:00:00.123,463] This sample demonstrates UICR.PROTECTEDMEM protection. |
| 78 | + [00:00:00.123,464] When protected memory is modified, the integrity check will fail |
| 79 | + [00:00:00.123,465] on the next boot, preventing the device from booting. |
| 80 | + [00:00:00.123,466] |
| 81 | + [00:00:00.123,467] Attempting to write test pattern 0xdeadbeef to protected memory... |
| 82 | + [00:00:00.123,468] Readback value: 0xdeadbeef |
| 83 | + [00:00:00.123,469] Write successful (in current boot). |
| 84 | + [00:00:00.123,470] |
| 85 | + [00:00:00.123,471] Rebooting... |
| 86 | + [00:00:00.123,472] After reboot, if protection is working correctly: |
| 87 | + [00:00:00.123,473] - The integrity check will detect the modification |
| 88 | + [00:00:00.123,474] - The device will fail to boot with an integrity error |
| 89 | + [00:00:00.123,475] - You should see a boot error status indicating PROTECTEDMEM integrity failure |
| 90 | + [00:00:00.123,476] |
| 91 | + [00:00:00.123,477] If protection is NOT working, the device will boot normally |
| 92 | + [00:00:00.123,478] and you will see this message again. |
| 93 | +
|
| 94 | +After the reboot, if protection is working correctly, the secondary firmware will boot instead of the main application. |
| 95 | +You should see the following output from the secondary firmware: |
| 96 | + |
| 97 | +.. code-block:: console |
| 98 | +
|
| 99 | + [00:00:01.234,567] *** Booting nRF Connect SDK v3.1.99-1baadd786027 *** |
| 100 | + [00:00:01.234,568] *** Using Zephyr OS v4.2.99-d7669eff2b94 *** |
| 101 | + [00:00:01.234,569] === Secondary Firmware Booted === |
| 102 | + [00:00:01.234,570] PROTECTEDMEM integrity check FAILED - device booted secondary firmware |
| 103 | + [00:00:01.234,571] This indicates that protected memory was modified and integrity check failed. |
| 104 | +
|
| 105 | +This demonstrates that the integrity check detected the modification and prevented the main application from booting. |
| 106 | + |
| 107 | +Configuration |
| 108 | +************* |
| 109 | + |
| 110 | +The sample uses the following key configurations: |
| 111 | + |
| 112 | +Device Tree Overlay |
| 113 | +=================== |
| 114 | + |
| 115 | +The ``app.overlay`` file relocates the ``periphconf_partition`` to be placed right after ``cpuapp_boot_partition``. |
| 116 | +The ``sysbuild.cmake`` file applies this same overlay to the UICR image so both images see the same partition layout: |
| 117 | + |
| 118 | +.. code-block:: dts |
| 119 | +
|
| 120 | + &mram1x { |
| 121 | + partitions { |
| 122 | + periphconf_partition: partition@40000 { |
| 123 | + reg = <0x40000 DT_SIZE_K(8)>; |
| 124 | + }; |
| 125 | + cpuapp_slot0_partition: partition@42000 { |
| 126 | + reg = <0x42000 DT_SIZE_K(328)>; |
| 127 | + }; |
| 128 | + }; |
| 129 | + }; |
| 130 | +
|
| 131 | +This places the partition at offset 0x40000 (right after ``cpuapp_boot_partition`` at 0x30000 with size 64KB). |
| 132 | + |
| 133 | +Kconfig Configuration |
| 134 | +===================== |
| 135 | + |
| 136 | +The ``sysbuild/uicr.conf`` file configures the PROTECTEDMEM size for the UICR image to cover both partitions: |
| 137 | + |
| 138 | +.. code-block:: cfg |
| 139 | +
|
| 140 | + CONFIG_GEN_UICR_PROTECTEDMEM_SIZE_BYTES=73728 |
| 141 | +
|
| 142 | +This covers: |
| 143 | +* ``cpuapp_boot_partition``: 64KB (0x10000) |
| 144 | +* ``periphconf_partition``: 8KB (0x2000) |
| 145 | +* Total: 72KB (0x12000) = 18 * 4KB blocks |
| 146 | + |
| 147 | +Note that the UICR image configuration is in ``sysbuild/uicr.conf``, not in the main application's Kconfig, as the UICR generation is handled by a separate sysbuild image. |
| 148 | + |
| 149 | +Secondary Firmware |
| 150 | +================== |
| 151 | + |
| 152 | +The sample includes a secondary firmware (in the ``secondary/`` directory) that boots automatically when the PROTECTEDMEM integrity check fails. The secondary firmware is configured in ``sysbuild/uicr.conf``: |
| 153 | + |
| 154 | +.. code-block:: cfg |
| 155 | +
|
| 156 | + CONFIG_GEN_UICR_SECONDARY=y |
| 157 | +
|
| 158 | +The secondary firmware is built as part of the sysbuild process (configured in ``sysbuild.cmake``) and is placed in the ``secondary_partition``. When IronSide SE detects that the PROTECTEDMEM integrity check has failed, it automatically boots the secondary firmware instead of the main application, allowing you to detect and handle the integrity violation. |
| 159 | + |
| 160 | +Dependencies |
| 161 | +************ |
| 162 | + |
| 163 | +This sample uses the following |NCS| subsystems: |
| 164 | + |
| 165 | +* UICR generation - Configures UICR.PROTECTEDMEM to protect the memory region and UICR.SECONDARY to enable secondary firmware boot |
| 166 | +* Sysbuild - Enables building the UICR image and secondary firmware with the protected memory configuration |
| 167 | + |
| 168 | +In addition, it uses the following Zephyr subsystems: |
| 169 | + |
| 170 | +* :ref:`Kernel <kernel>` - Provides basic system functionality and threading |
| 171 | +* :ref:`Console <console>` - Enables UART console output for debugging and user interaction |
| 172 | +* Device Tree - Defines the partition layout |
| 173 | + |
0 commit comments