Skip to content

Commit e0b58b4

Browse files
authored
Merge pull request #431 from arduino/mcuboot_rebased
Add support for secure bootloader
2 parents 883c1e9 + 1f70949 commit e0b58b4

19 files changed

+11209
-73
lines changed

Diff for: boards.txt

+24-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ edge_control.build.fpu=-mfpu=fpv4-sp-d16
1313
edge_control.build.float-abi=-mfloat-abi=softfp
1414
edge_control.build.board=EDGE_CONTROL
1515
edge_control.build.ldscript=linker_script.ld
16+
edge_control.build.postbuild.cmd=imgtool exit
1617
edge_control.compiler.mbed.arch.define=-DARDUINO_ARCH_NRF52840
1718
edge_control.compiler.mbed.defines={build.variant.path}/defines.txt
1819
edge_control.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
@@ -50,6 +51,7 @@ edge_control.bootloader.file=EDGE_CONTROL/bootloader.hex
5051
##############################################################
5152

5253
menu.split=Flash split
54+
menu.security=Security setting
5355

5456
envie_m7.name=Arduino Portenta H7 (M7 core)
5557
envie_m7.build.core=arduino
@@ -60,6 +62,9 @@ envie_m7.menu.split.50_50=1MB M7 + 1MB M4
6062
envie_m7.menu.split.75_25=1.5MB M7 + 0.5MB M4
6163
envie_m7.menu.split.100_0=2MB M7 + M4 in SDRAM
6264

65+
envie_m7.menu.security.none=None
66+
envie_m7.menu.security.sien=Signature + Encryption
67+
6368
envie_m7.build.variant=PORTENTA_H7_M7
6469
envie_m7.build.mcu=cortex-m7
6570
envie_m7.build.fpu=-mfpu=fpv5-d16
@@ -71,6 +76,15 @@ envie_m7.menu.split.100_0.build.extra_ldflags=-DCM4_BINARY_START=0x60000000
7176
envie_m7.build.architecture=cortex-m7
7277
envie_m7.build.board=PORTENTA_H7_M7
7378
envie_m7.build.ldscript=linker_script.ld
79+
envie_m7.build.slot_size=0x1E0000
80+
envie_m7.build.header_size=0x20000
81+
envie_m7.build.alignment=32
82+
envie_m7.build.version=1.2.3+4
83+
envie_m7.menu.security.sien.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" {tools.imgtool.flags}
84+
envie_m7.menu.security.sien.build.keys.keychain={runtime.hardware.path}/mbed/libraries/MCUboot/default_keys
85+
envie_m7.menu.security.sien.build.keys.sign_key=ecdsa-p256-signing-key.pem
86+
envie_m7.menu.security.sien.build.keys.encrypt_key=ecdsa-p256-encrypt-key.pem
87+
envie_m7.menu.security.none.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
7488
envie_m7.compiler.mbed.arch.define=
7589
envie_m7.compiler.mbed.defines={build.variant.path}/defines.txt
7690
envie_m7.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
@@ -98,8 +112,10 @@ envie_m7.upload.protocol=
98112
envie_m7.upload.transport=
99113
envie_m7.upload.vid=0x2341
100114
envie_m7.upload.pid=0x035b
101-
envie_m7.upload.address=0x08040000
102-
envie_m7.upload.interface=0
115+
envie_m7.menu.security.none.upload.interface=0
116+
envie_m7.menu.security.sien.upload.interface=2
117+
envie_m7.menu.security.none.upload.address=0x08040000
118+
envie_m7.menu.security.sien.upload.address=0xA0000000
103119
envie_m7.upload.use_1200bps_touch=true
104120
envie_m7.upload.wait_for_upload_port=true
105121
envie_m7.upload.native_usb=true
@@ -147,6 +163,7 @@ envie_m4.menu.split.100_0.build.extra_ldflags=-DCM4_BINARY_START=0x60000000 -DCM
147163
envie_m4.build.architecture=cortex-m4
148164
envie_m4.build.board=PORTENTA_H7_M4
149165
envie_m4.build.ldscript=linker_script.ld
166+
envie_m4.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
150167
envie_m4.compiler.mbed.arch.define=
151168
envie_m4.compiler.mbed.defines={build.variant.path}/defines.txt
152169
envie_m4.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
@@ -205,6 +222,7 @@ nano33ble.build.fpu=-mfpu=fpv4-sp-d16
205222
nano33ble.build.float-abi=-mfloat-abi=softfp
206223
nano33ble.build.board=ARDUINO_NANO33BLE
207224
nano33ble.build.ldscript=linker_script.ld
225+
nano33ble.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
208226
nano33ble.compiler.mbed.arch.define=-DARDUINO_ARCH_NRF52840
209227
nano33ble.compiler.mbed.defines={build.variant.path}/defines.txt
210228
nano33ble.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
@@ -258,6 +276,7 @@ nanorp2040connect.build.float-abi=
258276
nanorp2040connect.build.architecture=cortex-m0plus
259277
nanorp2040connect.build.board=NANO_RP2040_CONNECT
260278
nanorp2040connect.build.ldscript=linker_script.ld
279+
nanorp2040connect.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
261280
nanorp2040connect.compiler.mbed.arch.define=-DARDUINO_ARCH_RP2040
262281
nanorp2040connect.compiler.mbed.defines={build.variant.path}/defines.txt
263282
nanorp2040connect.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
@@ -309,6 +328,7 @@ pico.build.float-abi=
309328
pico.build.architecture=cortex-m0plus
310329
pico.build.board=RASPBERRY_PI_PICO
311330
pico.build.ldscript=linker_script.ld
331+
pico.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
312332
pico.compiler.mbed.arch.define=-DARDUINO_ARCH_RP2040
313333
pico.compiler.mbed.defines={build.variant.path}/defines.txt
314334
pico.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
@@ -352,6 +372,7 @@ nicla_sense.build.fpu=-mfpu=fpv4-sp-d16
352372
nicla_sense.build.float-abi=-mfloat-abi=softfp
353373
nicla_sense.build.board=NICLA
354374
nicla_sense.build.ldscript=linker_script.ld
375+
nicla_sense.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
355376
nicla_sense.compiler.mbed.arch.define=-DARDUINO_ARCH_NRF52832
356377
nicla_sense.compiler.mbed.defines={build.variant.path}/defines.txt
357378
nicla_sense.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
@@ -399,6 +420,7 @@ nicla_vision.build.extra_flags=
399420
nicla_vision.build.architecture=cortex-m7
400421
nicla_vision.build.board=NICLA_VISION
401422
nicla_vision.build.ldscript=linker_script.ld
423+
nicla_vision.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
402424
nicla_vision.compiler.mbed.arch.define=
403425
nicla_vision.compiler.mbed.defines={build.variant.path}/defines.txt
404426
nicla_vision.compiler.mbed.ldflags={build.variant.path}/ldflags.txt

Diff for: extras/package_index.json.NewTag.template

+5
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@
204204
"packager": "arduino",
205205
"version": "0.10.0-arduino1",
206206
"name": "dfu-util"
207+
},
208+
{
209+
"packager": "arduino",
210+
"version": "1.8.0_Arduino",
211+
"name": "imgtool"
207212
}
208213
]
209214
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgeXK282KRCbs1IrhU
3+
Mjv+HJ+nEG+6r3Nk0/UxvCjnyXKhRANCAARqySBMltaJ6NFuUQQChuiVCyLEyZUG
4+
T/Ub9tDjg9nRgWZu8gc7A9vk0d58Q3CNoonrG/q+Al5coBLcIzHB4Dew
5+
-----END PRIVATE KEY-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgx7NPA8ciVn4ZF6tp
3+
wW8dRJpfN3098/hTLmP1uVEEMr+hRANCAATVFjUmwzutTWeOQyTEmOlrLr4No/H0
4+
l4B7MTIH2ZWnF1dpQ3vpyKrQCgyGC+N/mYhRxPkimL5eqv2QPKJ0GEkF
5+
-----END PRIVATE KEY-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
This example shows how to confirm an update Sketch after a swap
3+
using MCUboot library.
4+
5+
Circuit:
6+
- Arduino Portenta H7 board
7+
8+
This example code is in the public domain.
9+
*/
10+
11+
#include <MCUboot.h>
12+
13+
// the setup function runs once when you press reset or power the board
14+
void setup() {
15+
// initialize digital pin LED_BUILTIN as an output.
16+
pinMode(LED_BUILTIN, OUTPUT);
17+
// set confirmed flag to avoid MCUboot reverts to previous application at next reset
18+
MCUboot::confirmSketch();
19+
}
20+
21+
// the loop function runs over and over again forever
22+
void loop() {
23+
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
24+
delay(100); // wait 100ms
25+
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
26+
delay(100); // wait 100ms
27+
}

Diff for: libraries/MCUboot/library.properties

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name=MCUboot
2+
version=0.0.1
3+
author=Arduino
4+
maintainer=Arduino <info@arduino.cc>
5+
sentence=Wrapper library for MCUboot
6+
paragraph=
7+
category=Other
8+
url=
9+
architectures=mbed,mbed_portenta
10+
precompiled=true
11+
ldflags=-lbootutil

Diff for: libraries/MCUboot/src/MCUboot.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "MCUboot.h"
2+
#include "bootutil.h"
3+
4+
void MCUboot::confirmSketch()
5+
{
6+
boot_set_confirmed();
7+
}
8+
9+
void MCUboot::applyUpdate(int permanent)
10+
{
11+
boot_set_pending(permanent);
12+
}
13+
14+
void MCUboot::bootDebug(int enable)
15+
{
16+
boot_set_debug(enable);
17+
}

Diff for: libraries/MCUboot/src/MCUboot.h

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef MCUboot_h_
2+
#define MCUboot_h_
3+
4+
class MCUboot
5+
{
6+
7+
public:
8+
static void confirmSketch(void);
9+
static void applyUpdate(int permanent);
10+
static void bootDebug(int enable);
11+
12+
};
13+
14+
#endif // MCUboot_h_

Diff for: libraries/MCUboot/src/bootutil.h

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef __BOOTUTIL_H
2+
#define __BOOTUTIL_H
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
int boot_set_confirmed(void);
9+
int boot_set_pending(int permanent);
10+
int boot_set_debug(int enable);
11+
12+
#ifdef __cplusplus
13+
}
14+
#endif
15+
16+
#endif /* __BOOTUTIL_H */

Diff for: libraries/MCUboot/src/cortex-m7/libbootutil.a

28.9 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include "QSPIFBlockDevice.h"
2+
#include "MBRBlockDevice.h"
3+
#include "LittleFileSystem.h"
4+
#include "FATFileSystem.h"
5+
6+
#ifndef CORE_CM7
7+
#error Format QSPI flash by uploading the sketch to the M7 core instead of the M4 core.
8+
#endif
9+
10+
11+
QSPIFBlockDevice root(QSPI_SO0, QSPI_SO1, QSPI_SO2, QSPI_SO3, QSPI_SCK, QSPI_CS, QSPIF_POLARITY_MODE_1, 40000000);
12+
mbed::MBRBlockDevice wifi_data(&root, 1);
13+
mbed::MBRBlockDevice ota_data(&root, 2);
14+
mbed::MBRBlockDevice user_data(&root, 3);
15+
mbed::FATFileSystem wifi_data_fs("wlan");
16+
mbed::FATFileSystem ota_data_fs("fs");
17+
mbed::FileSystem * user_data_fs;
18+
19+
bool waitResponse() {
20+
bool confirmation = false;
21+
while (confirmation == false) {
22+
if (Serial.available()) {
23+
char choice = Serial.read();
24+
switch (choice) {
25+
case 'y':
26+
case 'Y':
27+
confirmation = true;
28+
return true;
29+
break;
30+
case 'n':
31+
case 'N':
32+
confirmation = true;
33+
return false;
34+
break;
35+
default:
36+
continue;
37+
}
38+
}
39+
}
40+
}
41+
42+
void setup() {
43+
44+
Serial.begin(115200);
45+
while (!Serial);
46+
47+
Serial.println("Available partition schemes:");
48+
Serial.println("\nPartition scheme 1");
49+
Serial.println("Partition 1: WiFi firmware and certificates 1MB");
50+
Serial.println("Partition 2: OTA and user data 14MB");
51+
Serial.println("\nPartition scheme 2");
52+
Serial.println("Partition 1: WiFi firmware and certificates 1MB");
53+
Serial.println("Partition 2: OTA 5MB");
54+
Serial.println("Partition 3: User data 9MB"),
55+
Serial.println("\nDo you want to use partition scheme 1? Y/[n]");
56+
Serial.println("If No, partition scheme 2 will be used.");
57+
bool default_scheme = waitResponse();
58+
59+
Serial.println("\nWARNING! Running the sketch all the content of the QSPI flash will be erased.");
60+
Serial.println("Do you want to proceed? Y/[n]");
61+
62+
if (true == waitResponse()) {
63+
mbed::MBRBlockDevice::partition(&root, 1, 0x0B, 0, 1024 * 1024);
64+
if(default_scheme) {
65+
mbed::MBRBlockDevice::partition(&root, 3, 0x0B, 6 * 1024 * 1024, 0);
66+
mbed::MBRBlockDevice::partition(&root, 2, 0x0B, 1024 * 1024, 14 * 1024 * 1024);
67+
// use space from 15.5MB to 16 MB for another fw, memory mapped
68+
} else {
69+
mbed::MBRBlockDevice::partition(&root, 2, 0x0B, 1024 * 1024, 5 * 1024 * 1024);
70+
mbed::MBRBlockDevice::partition(&root, 3, 0x0B, 6 * 1024 * 1024, 9 * 1024 * 1024);
71+
// use space from 15.5MB to 16 MB for another fw, memory mapped
72+
}
73+
74+
int err = wifi_data_fs.reformat(&wifi_data);
75+
if (err) {
76+
Serial.println("Error formatting WiFi partition");
77+
}
78+
79+
err = ota_data_fs.reformat(&ota_data);
80+
if (err) {
81+
Serial.println("Error formatting OTA partition");
82+
}
83+
84+
if(!default_scheme) {
85+
Serial.println("\nDo you want to use LittleFS to format user data partition? Y/[n]");
86+
Serial.println("If No, FatFS will be used to format user partition.");
87+
88+
if (true == waitResponse()) {
89+
Serial.println("Formatting user partition with LittleFS.");
90+
user_data_fs = new mbed::LittleFileSystem("user");
91+
} else {
92+
Serial.println("Formatting user partition with FatFS.");
93+
user_data_fs = new mbed::FATFileSystem("user");
94+
}
95+
96+
err = user_data_fs->reformat(&user_data);
97+
if (err) {
98+
Serial.println("Error formatting user partition");
99+
}
100+
}
101+
Serial.println("\nQSPI Flash formatted!");
102+
}
103+
104+
Serial.println("It's now safe to reboot or disconnect your board.");
105+
}
106+
107+
void loop() {
108+
109+
}

Diff for: libraries/STM32H747_System/examples/STM32H747_getBootloaderInfo/STM32H747_getBootloaderInfo.ino

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
uint8_t* bootloader_data = (uint8_t*)(0x801F000);
2+
uint8_t* bootloader_identification = (uint8_t*)(0x80002F0);
23

34
void setup() {
45
Serial.begin(115200);
56
while (!Serial) {}
6-
7+
8+
uint8_t currentBootloaderVersion = bootloader_data[1];
9+
String currentBootloaderIdentifier = String(bootloader_identification, 15);
10+
11+
if(!currentBootloaderIdentifier.equals("MCUboot Arduino")) {
12+
currentBootloaderIdentifier = "Arduino loader";
13+
}
14+
15+
Serial.println(currentBootloaderIdentifier);
716
Serial.println("Magic Number (validation): " + String(bootloader_data[0], HEX));
817
Serial.println("Bootloader version: " + String(bootloader_data[1]));
918
Serial.println("Clock source: " + getClockSource(bootloader_data[2]));

0 commit comments

Comments
 (0)