Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d3fa563

Browse files
Merge pull request #672 from pennam/boot-v25
Bootloader v25 update proposal
2 parents d149870 + f48f635 commit d3fa563

File tree

11 files changed

+37700
-59073
lines changed

11 files changed

+37700
-59073
lines changed
File renamed without changes.
File renamed without changes.
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
This example enables secuity features of the MCUboot bootloader writing encryption
3+
and signing key into the microcontroller flash memory.
4+
5+
Once the keys are loaded you need to build and upload the future sketches enabling
6+
the Security Settings -> "Signing + Encryption" in the tools menu of the IDE. This
7+
will create an encrypted and signed binary conforming to the MCUboot image format
8+
using imgtool. See https://docs.mcuboot.com/design.html#image-format for more details
9+
about image format.
10+
11+
Writing the keys will also enable MCUboot image swap using a scratch area. This will
12+
increase the sketch update time after the upload, but also adds the possibility to
13+
revert to the previous image version if the update is not confirmed.
14+
See ConfirmSketch example for more details about setting the confirmed flag.
15+
16+
Circuit:
17+
- Arduino Portenta H7 board
18+
19+
This example code is in the public domain.
20+
*/
21+
22+
#include "FlashIAP.h"
23+
#include "QSPIFBlockDevice.h"
24+
#include "MBRBlockDevice.h"
25+
#include "LittleFileSystem.h"
26+
#include "FATFileSystem.h"
27+
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA)
28+
#include "ecdsa-p256-encrypt-key.h"
29+
#include "ecdsa-p256-signing-key.h"
30+
#else
31+
#error "Security features not available for this board"
32+
#endif
33+
34+
#ifndef CORE_CM7
35+
#error Update the bootloader by uploading the sketch to the M7 core instead of the M4 core.
36+
#endif
37+
38+
#define BOOTLOADER_ADDR (0x8000000)
39+
#define SIGNING_KEY_ADDR (0x8000300)
40+
#define ENCRYPT_KEY_ADDR (0x8000400)
41+
#define ENCRYPT_KEY_SIZE (0x0000100)
42+
#define SIGNING_KEY_SIZE (0x0000100)
43+
44+
mbed::FlashIAP flash;
45+
QSPIFBlockDevice root(QSPI_SO0, QSPI_SO1, QSPI_SO2, QSPI_SO3, QSPI_SCK, QSPI_CS, QSPIF_POLARITY_MODE_1, 40000000);
46+
47+
bool writeKeys = false;
48+
uint32_t bootloader_data_offset = 0x1F000;
49+
uint8_t* bootloader_data = (uint8_t*)(BOOTLOADER_ADDR + bootloader_data_offset);
50+
51+
uint32_t bootloader_identification_offset = 0x2F0;
52+
uint8_t* bootloader_identification = (uint8_t*)(BOOTLOADER_ADDR + bootloader_identification_offset);
53+
54+
void setup() {
55+
Serial.begin(115200);
56+
while (!Serial) {}
57+
58+
uint8_t currentBootloaderVersion = bootloader_data[1];
59+
String currentBootloaderIdentifier = String(bootloader_identification, 15);
60+
61+
if((currentBootloaderVersion > 24) && (currentBootloaderIdentifier.equals("MCUboot Arduino"))) {
62+
Serial.println("The sketch comes with a set of default keys to evaluate signing and encryption process");
63+
Serial.println("If you load the keys, you will need to upload the future sketches with Security Settings -> Signing + Encryption.");
64+
Serial.println("If you select Security Settings -> None, the sketches will not be executed.");
65+
Serial.println("Do you want to load the keys? Y/[n]");
66+
if (waitResponse()) {
67+
Serial.println("\nPlease notice that loading the keys will enable MCUboot Sketch swap. This will increase the sketch update time after the upload.");
68+
Serial.println("A violet LED will blink until the sketch is ready to run.");
69+
Serial.println("Do you want to proceed loading the default keys? Y/[n]");
70+
writeKeys = waitResponse();
71+
}
72+
} else {
73+
Serial.println("Security features not available for this bootloader version. Please update it using STM32H747_manageBootloader sketch");
74+
}
75+
76+
if (writeKeys) {
77+
applyUpdate();
78+
}
79+
Serial.println("It's now safe to reboot or disconnect your board.");
80+
}
81+
82+
void printProgress(uint32_t offset, uint32_t size, uint32_t threshold, bool reset) {
83+
static int percent_done = 0;
84+
if (reset == true) {
85+
percent_done = 0;
86+
Serial.println("Flashed " + String(percent_done) + "%");
87+
} else {
88+
uint32_t percent_done_new = offset * 100 / size;
89+
if (percent_done_new >= percent_done + threshold) {
90+
percent_done = percent_done_new;
91+
Serial.println("Flashed " + String(percent_done) + "%");
92+
}
93+
}
94+
}
95+
96+
bool waitResponse() {
97+
bool confirmation = false;
98+
while (confirmation == false) {
99+
if (Serial.available()) {
100+
char choice = Serial.read();
101+
switch (choice) {
102+
case 'y':
103+
case 'Y':
104+
confirmation = true;
105+
return true;
106+
break;
107+
case 'n':
108+
case 'N':
109+
confirmation = true;
110+
return false;
111+
break;
112+
default:
113+
continue;
114+
}
115+
}
116+
}
117+
}
118+
119+
void setupMCUBootOTAData() {
120+
mbed::MBRBlockDevice ota_data(&root, 2);
121+
mbed::FATFileSystem ota_data_fs("fs");
122+
123+
int err = ota_data_fs.reformat(&ota_data);
124+
if (err) {
125+
Serial.println("Error creating MCUboot files in OTA partition.");
126+
Serial.println("Run QSPIformat.ino sketch to format the QSPI flash and fix the issue.");
127+
}
128+
129+
FILE* fp = fopen("/fs/scratch.bin", "wb");
130+
const int scratch_file_size = 128 * 1024;
131+
const char buffer[128] = {0xFF};
132+
int size = 0;
133+
134+
Serial.println("\nCreating scratch file");
135+
printProgress(size, scratch_file_size, 10, true);
136+
while (size < scratch_file_size) {
137+
int ret = fwrite(buffer, sizeof(buffer), 1, fp);
138+
if (ret != 1) {
139+
Serial.println("Error writing scratch file");
140+
break;
141+
}
142+
size += sizeof(buffer);
143+
printProgress(size, scratch_file_size, 10, false);
144+
}
145+
fclose(fp);
146+
147+
fp = fopen("/fs/update.bin", "wb");
148+
const int update_file_size = 15 * 128 * 1024;
149+
size = 0;
150+
151+
Serial.println("\nCreating update file");
152+
printProgress(size, update_file_size, 10, true);
153+
while (size < update_file_size) {
154+
int ret = fwrite(buffer, sizeof(buffer), 1, fp);
155+
if (ret != 1) {
156+
Serial.println("Error writing scratch file");
157+
break;
158+
}
159+
size += sizeof(buffer);
160+
printProgress(size, update_file_size, 5, false);
161+
}
162+
163+
fclose(fp);
164+
}
165+
166+
void applyUpdate() {
167+
flash.init();
168+
setupMCUBootOTAData();
169+
flash.program(&enc_priv_key, ENCRYPT_KEY_ADDR, ENCRYPT_KEY_SIZE);
170+
flash.program(&ecdsa_pub_key, SIGNING_KEY_ADDR, SIGNING_KEY_SIZE);
171+
flash.deinit();
172+
Serial.println("\nSecurity features enabled. It's now safe to reboot or disconnect your board.");
173+
}
174+
175+
void loop() {
176+
delay(1000);
177+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /