Skip to content

Commit 15dfcad

Browse files
committed
Add dedicated sketch to enable MCUboot security features
1 parent 812e58d commit 15dfcad

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const unsigned char enc_priv_key[] {
2+
0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13,
3+
0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
4+
0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
5+
0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02,
6+
0x01, 0x01, 0x04, 0x20, 0x79, 0x72, 0xb6, 0xf3,
7+
0x62, 0x91, 0x09, 0xbb, 0x35, 0x22, 0xb8, 0x54,
8+
0x32, 0x3b, 0xfe, 0x1c, 0x9f, 0xa7, 0x10, 0x6f,
9+
0xba, 0xaf, 0x73, 0x64, 0xd3, 0xf5, 0x31, 0xbc,
10+
0x28, 0xe7, 0xc9, 0x72, 0xa1, 0x44, 0x03, 0x42,
11+
0x00, 0x04, 0x6a, 0xc9, 0x20, 0x4c, 0x96, 0xd6,
12+
0x89, 0xe8, 0xd1, 0x6e, 0x51, 0x04, 0x02, 0x86,
13+
0xe8, 0x95, 0x0b, 0x22, 0xc4, 0xc9, 0x95, 0x06,
14+
0x4f, 0xf5, 0x1b, 0xf6, 0xd0, 0xe3, 0x83, 0xd9,
15+
0xd1, 0x81, 0x66, 0x6e, 0xf2, 0x07, 0x3b, 0x03,
16+
0xdb, 0xe4, 0xd1, 0xde, 0x7c, 0x43, 0x70, 0x8d,
17+
0xa2, 0x89, 0xeb, 0x1b, 0xfa, 0xbe, 0x02, 0x5e,
18+
0x5c, 0xa0, 0x12, 0xdc, 0x23, 0x31, 0xc1, 0xe0,
19+
0x37, 0xb0,
20+
};
21+
const unsigned int enc_priv_key_len = 138;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const unsigned char ecdsa_pub_key[] {
2+
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
3+
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
4+
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
5+
0x42, 0x00, 0x04, 0xd5, 0x16, 0x35, 0x26, 0xc3,
6+
0x3b, 0xad, 0x4d, 0x67, 0x8e, 0x43, 0x24, 0xc4,
7+
0x98, 0xe9, 0x6b, 0x2e, 0xbe, 0x0d, 0xa3, 0xf1,
8+
0xf4, 0x97, 0x80, 0x7b, 0x31, 0x32, 0x07, 0xd9,
9+
0x95, 0xa7, 0x17, 0x57, 0x69, 0x43, 0x7b, 0xe9,
10+
0xc8, 0xaa, 0xd0, 0x0a, 0x0c, 0x86, 0x0b, 0xe3,
11+
0x7f, 0x99, 0x88, 0x51, 0xc4, 0xf9, 0x22, 0x98,
12+
0xbe, 0x5e, 0xaa, 0xfd, 0x90, 0x3c, 0xa2, 0x74,
13+
0x18, 0x49, 0x05,
14+
};
15+
const unsigned int ecdsa_pub_key_len = 91;
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#include "FlashIAP.h"
2+
#include "QSPIFBlockDevice.h"
3+
#include "MBRBlockDevice.h"
4+
#include "LittleFileSystem.h"
5+
#include "FATFileSystem.h"
6+
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA)
7+
#include "ecdsa-p256-encrypt-key.h"
8+
#include "ecdsa-p256-signing-key.h"
9+
#else
10+
#error "Security features not available for this board"
11+
#endif
12+
13+
#ifndef CORE_CM7
14+
#error Update the bootloader by uploading the sketch to the M7 core instead of the M4 core.
15+
#endif
16+
17+
#define BOOTLOADER_ADDR (0x8000000)
18+
#define SIGNING_KEY_ADDR (0x8000300)
19+
#define ENCRYPT_KEY_ADDR (0x8000400)
20+
#define ENCRYPT_KEY_SIZE (0x0000100)
21+
#define SIGNING_KEY_SIZE (0x0000100)
22+
23+
mbed::FlashIAP flash;
24+
QSPIFBlockDevice root(QSPI_SO0, QSPI_SO1, QSPI_SO2, QSPI_SO3, QSPI_SCK, QSPI_CS, QSPIF_POLARITY_MODE_1, 40000000);
25+
26+
bool writeKeys = false;
27+
uint32_t bootloader_data_offset = 0x1F000;
28+
uint8_t* bootloader_data = (uint8_t*)(BOOTLOADER_ADDR + bootloader_data_offset);
29+
30+
uint32_t bootloader_identification_offset = 0x2F0;
31+
uint8_t* bootloader_identification = (uint8_t*)(BOOTLOADER_ADDR + bootloader_identification_offset);
32+
33+
void setup() {
34+
Serial.begin(115200);
35+
while (!Serial) {}
36+
37+
uint8_t currentBootloaderVersion = bootloader_data[1];
38+
String currentBootloaderIdentifier = String(bootloader_identification, 15);
39+
40+
if((currentBootloaderVersion > 24) && (currentBootloaderIdentifier.equals("MCUboot Arduino"))) {
41+
Serial.println("\nThe sketch comes with a set of default keys to evaluate signing and encryption process");
42+
Serial.println("If you load the keys, you will need to upload the future sketches with Security Settings -> Signing + Encryption.");
43+
Serial.println("If you select Security Settings -> None, the sketches will not be executed.");
44+
Serial.println("Do you want to load the keys? Y/[n]");
45+
if (waitResponse()) {
46+
Serial.println("\nPlease notice that loading the keys will enable MCUboot Sketch swap. This will increase the sketch update time after the upload.");
47+
Serial.println("A violet LED will blink until the sketch is ready to run.");
48+
Serial.println("Do you want to proceed loading the default keys? Y/[n]");
49+
writeKeys = waitResponse();
50+
}
51+
}
52+
53+
if (writeKeys) {
54+
applyUpdate();
55+
}
56+
Serial.println("It's now safe to reboot or disconnect your board.");
57+
}
58+
59+
void printProgress(uint32_t offset, uint32_t size, uint32_t threshold, bool reset) {
60+
static int percent_done = 0;
61+
if (reset == true) {
62+
percent_done = 0;
63+
Serial.println("Flashed " + String(percent_done) + "%");
64+
} else {
65+
uint32_t percent_done_new = offset * 100 / size;
66+
if (percent_done_new >= percent_done + threshold) {
67+
percent_done = percent_done_new;
68+
Serial.println("Flashed " + String(percent_done) + "%");
69+
}
70+
}
71+
}
72+
73+
bool waitResponse() {
74+
bool confirmation = false;
75+
while (confirmation == false) {
76+
if (Serial.available()) {
77+
char choice = Serial.read();
78+
switch (choice) {
79+
case 'y':
80+
case 'Y':
81+
confirmation = true;
82+
return true;
83+
break;
84+
case 'n':
85+
case 'N':
86+
confirmation = true;
87+
return false;
88+
break;
89+
default:
90+
continue;
91+
}
92+
}
93+
}
94+
}
95+
96+
void setupMCUBootOTAData() {
97+
mbed::MBRBlockDevice ota_data(&root, 2);
98+
mbed::FATFileSystem ota_data_fs("fs");
99+
100+
int err = ota_data_fs.reformat(&ota_data);
101+
if (err) {
102+
Serial.println("Error creating MCUboot files in OTA partition.");
103+
Serial.println("Run QSPIformat.ino sketch to format the QSPI flash and fix the issue.");
104+
}
105+
106+
FILE* fp = fopen("/fs/scratch.bin", "wb");
107+
const int scratch_file_size = 128 * 1024;
108+
const char buffer[128] = {0xFF};
109+
int size = 0;
110+
111+
Serial.println("\nCreating scratch file");
112+
printProgress(size, scratch_file_size, 10, true);
113+
while (size < scratch_file_size) {
114+
int ret = fwrite(buffer, sizeof(buffer), 1, fp);
115+
if (ret != 1) {
116+
Serial.println("Error writing scratch file");
117+
break;
118+
}
119+
size += sizeof(buffer);
120+
printProgress(size, scratch_file_size, 10, false);
121+
}
122+
fclose(fp);
123+
124+
fp = fopen("/fs/update.bin", "wb");
125+
const int update_file_size = 15 * 128 * 1024;
126+
size = 0;
127+
128+
Serial.println("\nCreating update file");
129+
printProgress(size, update_file_size, 10, true);
130+
while (size < update_file_size) {
131+
int ret = fwrite(buffer, sizeof(buffer), 1, fp);
132+
if (ret != 1) {
133+
Serial.println("Error writing scratch file");
134+
break;
135+
}
136+
size += sizeof(buffer);
137+
printProgress(size, update_file_size, 5, false);
138+
}
139+
140+
fclose(fp);
141+
}
142+
143+
void applyUpdate() {
144+
flash.init();
145+
setupMCUBootOTAData();
146+
flash.program(&enc_priv_key, ENCRYPT_KEY_ADDR, ENCRYPT_KEY_SIZE);
147+
flash.program(&ecdsa_pub_key, SIGNING_KEY_ADDR, SIGNING_KEY_SIZE);
148+
Serial.println("Flashed 100%");
149+
flash.deinit();
150+
Serial.println("\nBootloader update complete. It's now safe to reboot or disconnect your board.");
151+
}
152+
153+
void loop() {
154+
delay(1000);
155+
}

0 commit comments

Comments
 (0)