Skip to content

Add support for secure bootloader #431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ edge_control.build.fpu=-mfpu=fpv4-sp-d16
edge_control.build.float-abi=-mfloat-abi=softfp
edge_control.build.board=EDGE_CONTROL
edge_control.build.ldscript=linker_script.ld
edge_control.build.postbuild.cmd=imgtool exit
edge_control.compiler.mbed.arch.define=-DARDUINO_ARCH_NRF52840
edge_control.compiler.mbed.defines={build.variant.path}/defines.txt
edge_control.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
Expand Down Expand Up @@ -50,6 +51,7 @@ edge_control.bootloader.file=EDGE_CONTROL/bootloader.hex
##############################################################

menu.split=Flash split
menu.security=Security setting

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

envie_m7.menu.security.none=None
envie_m7.menu.security.sien=Signature + Encryption

envie_m7.build.variant=PORTENTA_H7_M7
envie_m7.build.mcu=cortex-m7
envie_m7.build.fpu=-mfpu=fpv5-d16
Expand All @@ -71,6 +76,15 @@ envie_m7.menu.split.100_0.build.extra_ldflags=-DCM4_BINARY_START=0x60000000
envie_m7.build.architecture=cortex-m7
envie_m7.build.board=PORTENTA_H7_M7
envie_m7.build.ldscript=linker_script.ld
envie_m7.build.slot_size=0x1E0000
envie_m7.build.header_size=0x20000
envie_m7.build.alignment=32
envie_m7.build.version=1.2.3+4
envie_m7.menu.security.sien.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" {tools.imgtool.flags}
envie_m7.menu.security.sien.build.keys.keychain={runtime.hardware.path}/mbed/libraries/MCUboot/default_keys
envie_m7.menu.security.sien.build.keys.sign_key=ecdsa-p256-signing-key.pem
envie_m7.menu.security.sien.build.keys.encrypt_key=ecdsa-p256-encrypt-key.pem
envie_m7.menu.security.none.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
envie_m7.compiler.mbed.arch.define=
envie_m7.compiler.mbed.defines={build.variant.path}/defines.txt
envie_m7.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
Expand Down Expand Up @@ -98,8 +112,10 @@ envie_m7.upload.protocol=
envie_m7.upload.transport=
envie_m7.upload.vid=0x2341
envie_m7.upload.pid=0x035b
envie_m7.upload.address=0x08040000
envie_m7.upload.interface=0
envie_m7.menu.security.none.upload.interface=0
envie_m7.menu.security.sien.upload.interface=2
envie_m7.menu.security.none.upload.address=0x08040000
envie_m7.menu.security.sien.upload.address=0xA0000000
envie_m7.upload.use_1200bps_touch=true
envie_m7.upload.wait_for_upload_port=true
envie_m7.upload.native_usb=true
Expand Down Expand Up @@ -147,6 +163,7 @@ envie_m4.menu.split.100_0.build.extra_ldflags=-DCM4_BINARY_START=0x60000000 -DCM
envie_m4.build.architecture=cortex-m4
envie_m4.build.board=PORTENTA_H7_M4
envie_m4.build.ldscript=linker_script.ld
envie_m4.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
envie_m4.compiler.mbed.arch.define=
envie_m4.compiler.mbed.defines={build.variant.path}/defines.txt
envie_m4.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
Expand Down Expand Up @@ -205,6 +222,7 @@ nano33ble.build.fpu=-mfpu=fpv4-sp-d16
nano33ble.build.float-abi=-mfloat-abi=softfp
nano33ble.build.board=ARDUINO_NANO33BLE
nano33ble.build.ldscript=linker_script.ld
nano33ble.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
nano33ble.compiler.mbed.arch.define=-DARDUINO_ARCH_NRF52840
nano33ble.compiler.mbed.defines={build.variant.path}/defines.txt
nano33ble.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
Expand Down Expand Up @@ -258,6 +276,7 @@ nanorp2040connect.build.float-abi=
nanorp2040connect.build.architecture=cortex-m0plus
nanorp2040connect.build.board=NANO_RP2040_CONNECT
nanorp2040connect.build.ldscript=linker_script.ld
nanorp2040connect.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
nanorp2040connect.compiler.mbed.arch.define=-DARDUINO_ARCH_RP2040
nanorp2040connect.compiler.mbed.defines={build.variant.path}/defines.txt
nanorp2040connect.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
Expand Down Expand Up @@ -309,6 +328,7 @@ pico.build.float-abi=
pico.build.architecture=cortex-m0plus
pico.build.board=RASPBERRY_PI_PICO
pico.build.ldscript=linker_script.ld
pico.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
pico.compiler.mbed.arch.define=-DARDUINO_ARCH_RP2040
pico.compiler.mbed.defines={build.variant.path}/defines.txt
pico.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
Expand Down Expand Up @@ -352,6 +372,7 @@ nicla_sense.build.fpu=-mfpu=fpv4-sp-d16
nicla_sense.build.float-abi=-mfloat-abi=softfp
nicla_sense.build.board=NICLA
nicla_sense.build.ldscript=linker_script.ld
nicla_sense.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
nicla_sense.compiler.mbed.arch.define=-DARDUINO_ARCH_NRF52832
nicla_sense.compiler.mbed.defines={build.variant.path}/defines.txt
nicla_sense.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
Expand Down Expand Up @@ -399,6 +420,7 @@ nicla_vision.build.extra_flags=
nicla_vision.build.architecture=cortex-m7
nicla_vision.build.board=NICLA_VISION
nicla_vision.build.ldscript=linker_script.ld
nicla_vision.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit
nicla_vision.compiler.mbed.arch.define=
nicla_vision.compiler.mbed.defines={build.variant.path}/defines.txt
nicla_vision.compiler.mbed.ldflags={build.variant.path}/ldflags.txt
Expand Down
5 changes: 5 additions & 0 deletions extras/package_index.json.NewTag.template
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@
"packager": "arduino",
"version": "0.10.0-arduino1",
"name": "dfu-util"
},
{
"packager": "arduino",
"version": "1.8.0_Arduino",
"name": "imgtool"
}
]
},
Expand Down
5 changes: 5 additions & 0 deletions libraries/MCUboot/default_keys/ecdsa-p256-encrypt-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgeXK282KRCbs1IrhU
Mjv+HJ+nEG+6r3Nk0/UxvCjnyXKhRANCAARqySBMltaJ6NFuUQQChuiVCyLEyZUG
T/Ub9tDjg9nRgWZu8gc7A9vk0d58Q3CNoonrG/q+Al5coBLcIzHB4Dew
-----END PRIVATE KEY-----
5 changes: 5 additions & 0 deletions libraries/MCUboot/default_keys/ecdsa-p256-signing-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgx7NPA8ciVn4ZF6tp
wW8dRJpfN3098/hTLmP1uVEEMr+hRANCAATVFjUmwzutTWeOQyTEmOlrLr4No/H0
l4B7MTIH2ZWnF1dpQ3vpyKrQCgyGC+N/mYhRxPkimL5eqv2QPKJ0GEkF
-----END PRIVATE KEY-----
27 changes: 27 additions & 0 deletions libraries/MCUboot/examples/confirmSketch/confirmSketch.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
This example shows how to confirm an update Sketch after a swap
using MCUboot library.

Circuit:
- Arduino Portenta H7 board

This example code is in the public domain.
*/

#include <MCUboot.h>

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
// set confirmed flag to avoid MCUboot reverts to previous application at next reset
MCUboot::confirmSketch();
}

// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(100); // wait 100ms
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(100); // wait 100ms
}
11 changes: 11 additions & 0 deletions libraries/MCUboot/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name=MCUboot
version=0.0.1
author=Arduino
maintainer=Arduino <info@arduino.cc>
sentence=Wrapper library for MCUboot
paragraph=
category=Other
url=
architectures=mbed,mbed_portenta
precompiled=true
ldflags=-lbootutil
17 changes: 17 additions & 0 deletions libraries/MCUboot/src/MCUboot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "MCUboot.h"
#include "bootutil.h"

void MCUboot::confirmSketch()
{
boot_set_confirmed();
}

void MCUboot::applyUpdate(int permanent)
{
boot_set_pending(permanent);
}

void MCUboot::bootDebug(int enable)
{
boot_set_debug(enable);
}
14 changes: 14 additions & 0 deletions libraries/MCUboot/src/MCUboot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef MCUboot_h_
#define MCUboot_h_

class MCUboot
{

public:
static void confirmSketch(void);
static void applyUpdate(int permanent);
static void bootDebug(int enable);

};

#endif // MCUboot_h_
16 changes: 16 additions & 0 deletions libraries/MCUboot/src/bootutil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef __BOOTUTIL_H
#define __BOOTUTIL_H

#ifdef __cplusplus
extern "C" {
#endif

int boot_set_confirmed(void);
int boot_set_pending(int permanent);
int boot_set_debug(int enable);

#ifdef __cplusplus
}
#endif

#endif /* __BOOTUTIL_H */
Binary file added libraries/MCUboot/src/cortex-m7/libbootutil.a
Binary file not shown.
109 changes: 109 additions & 0 deletions libraries/STM32H747_System/examples/QSPIFormat/QSPIFormat.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "QSPIFBlockDevice.h"
#include "MBRBlockDevice.h"
#include "LittleFileSystem.h"
#include "FATFileSystem.h"

#ifndef CORE_CM7
#error Format QSPI flash by uploading the sketch to the M7 core instead of the M4 core.
#endif


QSPIFBlockDevice root(QSPI_SO0, QSPI_SO1, QSPI_SO2, QSPI_SO3, QSPI_SCK, QSPI_CS, QSPIF_POLARITY_MODE_1, 40000000);
mbed::MBRBlockDevice wifi_data(&root, 1);
mbed::MBRBlockDevice ota_data(&root, 2);
mbed::MBRBlockDevice user_data(&root, 3);
mbed::FATFileSystem wifi_data_fs("wlan");
mbed::FATFileSystem ota_data_fs("fs");
mbed::FileSystem * user_data_fs;

bool waitResponse() {
bool confirmation = false;
while (confirmation == false) {
if (Serial.available()) {
char choice = Serial.read();
switch (choice) {
case 'y':
case 'Y':
confirmation = true;
return true;
break;
case 'n':
case 'N':
confirmation = true;
return false;
break;
default:
continue;
}
}
}
}

void setup() {

Serial.begin(115200);
while (!Serial);

Serial.println("Available partition schemes:");
Serial.println("\nPartition scheme 1");
Serial.println("Partition 1: WiFi firmware and certificates 1MB");
Serial.println("Partition 2: OTA and user data 14MB");
Serial.println("\nPartition scheme 2");
Serial.println("Partition 1: WiFi firmware and certificates 1MB");
Serial.println("Partition 2: OTA 5MB");
Serial.println("Partition 3: User data 9MB"),
Serial.println("\nDo you want to use partition scheme 1? Y/[n]");
Serial.println("If No, partition scheme 2 will be used.");
bool default_scheme = waitResponse();

Serial.println("\nWARNING! Running the sketch all the content of the QSPI flash will be erased.");
Serial.println("Do you want to proceed? Y/[n]");

if (true == waitResponse()) {
mbed::MBRBlockDevice::partition(&root, 1, 0x0B, 0, 1024 * 1024);
if(default_scheme) {
mbed::MBRBlockDevice::partition(&root, 3, 0x0B, 6 * 1024 * 1024, 0);
mbed::MBRBlockDevice::partition(&root, 2, 0x0B, 1024 * 1024, 14 * 1024 * 1024);
// use space from 15.5MB to 16 MB for another fw, memory mapped
} else {
mbed::MBRBlockDevice::partition(&root, 2, 0x0B, 1024 * 1024, 5 * 1024 * 1024);
mbed::MBRBlockDevice::partition(&root, 3, 0x0B, 6 * 1024 * 1024, 9 * 1024 * 1024);
// use space from 15.5MB to 16 MB for another fw, memory mapped
}

int err = wifi_data_fs.reformat(&wifi_data);
if (err) {
Serial.println("Error formatting WiFi partition");
}

err = ota_data_fs.reformat(&ota_data);
if (err) {
Serial.println("Error formatting OTA partition");
}

if(!default_scheme) {
Serial.println("\nDo you want to use LittleFS to format user data partition? Y/[n]");
Serial.println("If No, FatFS will be used to format user partition.");

if (true == waitResponse()) {
Serial.println("Formatting user partition with LittleFS.");
user_data_fs = new mbed::LittleFileSystem("user");
} else {
Serial.println("Formatting user partition with FatFS.");
user_data_fs = new mbed::FATFileSystem("user");
}

err = user_data_fs->reformat(&user_data);
if (err) {
Serial.println("Error formatting user partition");
}
}
Serial.println("\nQSPI Flash formatted!");
}

Serial.println("It's now safe to reboot or disconnect your board.");
}

void loop() {

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
uint8_t* bootloader_data = (uint8_t*)(0x801F000);
uint8_t* bootloader_identification = (uint8_t*)(0x80002F0);

void setup() {
Serial.begin(115200);
while (!Serial) {}


uint8_t currentBootloaderVersion = bootloader_data[1];
String currentBootloaderIdentifier = String(bootloader_identification, 15);

if(!currentBootloaderIdentifier.equals("MCUboot Arduino")) {
currentBootloaderIdentifier = "Arduino loader";
}

Serial.println(currentBootloaderIdentifier);
Serial.println("Magic Number (validation): " + String(bootloader_data[0], HEX));
Serial.println("Bootloader version: " + String(bootloader_data[1]));
Serial.println("Clock source: " + getClockSource(bootloader_data[2]));
Expand Down
Loading