Skip to content

Commit 5c5f498

Browse files
committed
[nrf noup] zephyr: firmware_loader bootconf
support for powerup protection mode Signed-off-by: Mateusz Michalek <mateusz.michalek@nordicsemi.no>
1 parent 8c46ed8 commit 5c5f498

3 files changed

Lines changed: 119 additions & 8 deletions

File tree

boot/zephyr/Kconfig

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,11 +589,21 @@ config NCS_MCUBOOT_DISABLE_SELF_RWX_SUPPORTED
589589
default y if SOC_NRF54LM20A_CPUAPP || SOC_NRF54LM20B_CPUAPP
590590
default y if SOC_NRF54LS05A_CPUAPP || SOC_NRF54LS05B_CPUAPP
591591

592+
config NCS_MCUBOOT_BOOTCONF_LOCK_WRITES
593+
bool "Use BOOTCONF-backed MCUboot write protection"
594+
depends on NCS_MCUBOOT_DISABLE_SELF_RWX_SUPPORTED
595+
select NCS_MCUBOOT_DISABLE_SELF_RWX
596+
help
597+
MCUboot is protected using UICR BOOTCONF programmed by bootconf.hex.
598+
This option is enabled by sysbuild when
599+
SB_CONFIG_MCUBOOT_BOOTCONF_LOCK_WRITES is set.
600+
592601
config NCS_MCUBOOT_DISABLE_SELF_RWX
593602
bool "Disable read and execution on self NVM"
594-
depends on NCS_MCUBOOT_DISABLE_SELF_RWX_SUPPORTED && !FPROTECT
603+
depends on NCS_MCUBOOT_DISABLE_SELF_RWX_SUPPORTED
604+
depends on !FPROTECT || NCS_MCUBOOT_BOOTCONF_LOCK_WRITES
595605
help
596-
Sets RRAMC's region no.4 protection before jumping to application.
606+
Sets RRAMC region protection before jumping to application.
597607
It disables reads writes and execution memory area which holds MCUBOOT.
598608

599609
config NCS_MCUBOOT_DISABLE_SELF_RWX_SKIP_SIZE

boot/zephyr/firmware_loader.c

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,66 @@
2020
#ifdef CONFIG_NRF_MCUBOOT_BOOT_REQUEST
2121
#include <bootutil/boot_request.h>
2222
#endif /* CONFIG_NRF_MCUBOOT_BOOT_REQUEST */
23+
#if defined(CONFIG_FPROTECT) && defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
24+
#include <fprotect.h>
25+
#endif
26+
27+
#define IMAGE_TLV_INSTALLER_IMAGE 0xa0
2328

2429
BOOT_LOG_MODULE_DECLARE(mcuboot);
2530

2631
/* Variables passed outside of unit via poiters. */
2732
static const struct flash_area *_fa_p;
2833
static struct image_header _hdr = { 0 };
2934

35+
#if defined(CONFIG_FPROTECT) && defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
36+
static bool boot_image_is_installer(const struct flash_area *fa_p,
37+
const struct image_header *hdr)
38+
{
39+
struct image_tlv_iter it;
40+
uint32_t off;
41+
uint16_t len;
42+
uint8_t installer = 0;
43+
int rc;
44+
45+
if (hdr->ih_protect_tlv_size == 0) {
46+
return false;
47+
}
48+
49+
rc = bootutil_tlv_iter_begin(&it, hdr, fa_p, IMAGE_TLV_INSTALLER_IMAGE, true);
50+
if (rc != 0) {
51+
return false;
52+
}
53+
54+
rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
55+
if (rc != 0 || len != sizeof(installer)) {
56+
return false;
57+
}
58+
59+
rc = LOAD_IMAGE_DATA(hdr, fa_p, off, &installer, sizeof(installer));
60+
61+
return rc == 0 && installer == 1;
62+
}
63+
64+
static int protect_firmware_loader(void)
65+
{
66+
const struct flash_area *fa_p;
67+
int rc;
68+
69+
rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(0), &fa_p);
70+
if (rc != 0) {
71+
return rc;
72+
}
73+
74+
rc = fprotect_area(flash_area_get_off(fa_p), flash_area_get_size(fa_p));
75+
flash_area_close(fa_p);
76+
77+
return rc;
78+
}
79+
#else
80+
#define boot_image_is_installer(_fa_p, _hdr) false
81+
#endif
82+
3083
#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT) || defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
3184
/**
3285
* Validate hash of a primary boot image.
@@ -110,7 +163,7 @@ boot_image_validate_once(const struct flash_area *fa_p,
110163
*
111164
* @return FIH_SUCCESS on success; non-zero on failure.
112165
*/
113-
static fih_ret validate_image_slot(int slot, struct boot_rsp *rsp)
166+
static fih_ret validate_image_slot(int slot, struct boot_rsp *rsp, bool *is_installer)
114167
{
115168
int rc = -1;
116169
FIH_DECLARE(fih_rc, FIH_FAILURE);
@@ -142,6 +195,7 @@ static fih_ret validate_image_slot(int slot, struct boot_rsp *rsp)
142195
rsp->br_flash_dev_id = flash_area_get_device_id(_fa_p);
143196
rsp->br_image_off = flash_area_get_off(_fa_p);
144197
rsp->br_hdr = &_hdr;
198+
*is_installer = boot_image_is_installer(_fa_p, &_hdr);
145199

146200
other:
147201
flash_area_close(_fa_p);
@@ -163,6 +217,7 @@ fih_ret
163217
boot_go(struct boot_rsp *rsp)
164218
{
165219
bool boot_firmware_loader = false;
220+
bool booting_installer = false;
166221
FIH_DECLARE(fih_rc, FIH_FAILURE);
167222

168223
BOOT_LOG_DBG("boot_go: firmware loader");
@@ -194,18 +249,33 @@ boot_go(struct boot_rsp *rsp)
194249

195250
/* Check if firmware loader button is pressed. TODO: check all entrance methods */
196251
if (boot_firmware_loader == true) {
197-
FIH_CALL(validate_image_slot, fih_rc, FLASH_AREA_IMAGE_SECONDARY(0), rsp);
252+
FIH_CALL(validate_image_slot, fih_rc, FLASH_AREA_IMAGE_SECONDARY(0), rsp,
253+
&booting_installer);
198254

199255
if (FIH_EQ(fih_rc, FIH_SUCCESS)) {
256+
#if defined(CONFIG_FPROTECT) && defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
257+
if (protect_firmware_loader() != 0) {
258+
FIH_RET(FIH_FAILURE);
259+
}
260+
#endif
200261
FIH_RET(fih_rc);
201262
}
202263
}
203264

204-
FIH_CALL(validate_image_slot, fih_rc, FLASH_AREA_IMAGE_PRIMARY(0), rsp);
265+
FIH_CALL(validate_image_slot, fih_rc, FLASH_AREA_IMAGE_PRIMARY(0), rsp,
266+
&booting_installer);
205267

206268
#ifdef CONFIG_BOOT_FIRMWARE_LOADER_NO_APPLICATION
207269
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
208-
FIH_CALL(validate_image_slot, fih_rc, FLASH_AREA_IMAGE_SECONDARY(0), rsp);
270+
FIH_CALL(validate_image_slot, fih_rc, FLASH_AREA_IMAGE_SECONDARY(0), rsp,
271+
&booting_installer);
272+
}
273+
#endif
274+
275+
#if defined(CONFIG_FPROTECT) && defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
276+
if (FIH_EQ(fih_rc, FIH_SUCCESS) && !booting_installer &&
277+
protect_firmware_loader() != 0) {
278+
FIH_RET(FIH_FAILURE);
209279
}
210280
#endif
211281

boot/zephyr/main.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,12 @@ K_SEM_DEFINE(boot_log_sem, 1, 1);
188188
#define RRAMC_REGION_RWX_LSB 0
189189
#define RRAMC_REGION_RWX_WIDTH 3
190190

191+
#if defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
192+
#define RRAMC_REGION_NUMBER 3
193+
#else
191194
#define RRAMC_REGION_NUMBER 4
195+
#endif
196+
192197
#define NRF_RRAM_REGION_SIZE_UNIT 0x400
193198
#define NRF_RRAM_REGION_ADDRESS_RESOLUTION 0x400
194199

@@ -206,9 +211,11 @@ K_SEM_DEFINE(boot_log_sem, 1, 1);
206211
#define RRAMC_REGION_CONFIG_H (((uint32_t)(&(RRAMC_REGION_CONFIG))) >> 16)
207212
#define RRAMC_REGION_CONFIG_L (((uint32_t)(&(RRAMC_REGION_CONFIG))) & 0x0000fffful)
208213

214+
#if !defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
209215
#define RRAMC_REGION_ADDRESS NRF_RRAMC->REGION[RRAMC_REGION_NUMBER].ADDRESS
210216
#define RRAMC_REGION_ADDRESS_H (((uint32_t)(&(RRAMC_REGION_ADDRESS))) >> 16)
211217
#define RRAMC_REGION_ADDRESS_L (((uint32_t)(&(RRAMC_REGION_ADDRESS))) & 0x0000fffful)
218+
#endif
212219

213220
BUILD_ASSERT((PROTECTED_REGION_START % NRF_RRAM_REGION_ADDRESS_RESOLUTION) == 0,
214221
"Start of protected region is not aligned - not possible to protect");
@@ -336,6 +343,23 @@ static void __ramfunc jump_in(struct arm_vector_table *vt)
336343
#endif /* CONFIG_MCUBOOT_CLEANUP_RAM */
337344

338345
#ifdef CONFIG_NCS_MCUBOOT_DISABLE_SELF_RWX
346+
#if defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
347+
".thumb_func\n"
348+
"region_disable_rwx:\n"
349+
" movw r1, %6\n"
350+
" movt r1, %7\n"
351+
" ldr r2, [r1]\n"
352+
/* Size should be set by bootconf.hex at reset. */
353+
" ldr r5, =%12\n"
354+
" ands r4, r2, r5\n"
355+
" cbnz r4, clear_rwx\n"
356+
" movt r2, %8\n"
357+
"clear_rwx:\n"
358+
" bfc r2, %9, %10\n"
359+
" orr r2, %11\n"
360+
" str r2, [r1]\n"
361+
" dsb\n"
362+
#else
339363
".thumb_func\n"
340364
"region_disable_rwx:\n"
341365
" movw r1, %6\n"
@@ -364,6 +388,7 @@ static void __ramfunc jump_in(struct arm_vector_table *vt)
364388
" orr r2, %11\n"
365389
" str r2, [r1]\n"
366390
" dsb\n"
391+
#endif /* CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES */
367392
/* Next assembly line is important for current function */
368393

369394
#endif /* CONFIG_NCS_MCUBOOT_DISABLE_SELF_RWX */
@@ -383,12 +408,16 @@ static void __ramfunc jump_in(struct arm_vector_table *vt)
383408
"i" ((PROTECTED_REGION_SIZE) / (NRF_RRAM_REGION_SIZE_UNIT)),
384409
"i" (RRAMC_REGION_RWX_LSB),
385410
"i" (RRAMC_REGION_RWX_WIDTH),
386-
"i" (RRAMC_REGION_CONFIG_LOCK_Msk),
387-
"i" (RRAMC_REGION_CONFIG_SIZE_Msk),
411+
"i" (RRAMC_REGION_CONFIG_LOCK_Msk)
412+
#if !defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
413+
, "i" (RRAMC_REGION_CONFIG_SIZE_Msk),
388414
"i" (RRAMC_REGION_ADDRESS_L),
389415
"i" (RRAMC_REGION_ADDRESS_H),
390416
"i" (PROTECTED_REGION_START_L),
391417
"i" (PROTECTED_REGION_START_H)
418+
#else
419+
, "i" (RRAMC_REGION_CONFIG_SIZE_Msk)
420+
#endif
392421
#endif /* CONFIG_NCS_MCUBOOT_DISABLE_SELF_RWX */
393422
: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "memory"
394423
);
@@ -972,6 +1001,7 @@ int main(void)
9721001
nrf_crypto_keys_housekeeping();
9731002

9741003
#ifdef CONFIG_FPROTECT
1004+
#if !defined(CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES)
9751005
#ifdef CONFIG_SOC_SERIES_NRF54L
9761006
#if defined(CONFIG_SOC_NRF54L15) || defined(CONFIG_SOC_NRF54L10) || defined(CONFIG_SOC_NRF54L05)
9771007
BUILD_ASSERT(FPROTECT_REGION_SIZE <= (62 * 1024), "Can not FPROTECT region that big");
@@ -989,6 +1019,7 @@ int main(void)
9891019
while (1)
9901020
;
9911021
}
1022+
#endif /* !CONFIG_NCS_MCUBOOT_BOOTCONF_LOCK_WRITES */
9921023

9931024
/* Lock back PCD used for CPUNET application udapte */
9941025
#if defined(CONFIG_SOC_NRF5340_CPUAPP) && CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 && \

0 commit comments

Comments
 (0)