Skip to content
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

Bootloader v25 update proposal #672

Merged
merged 9 commits into from
May 17, 2023
155 changes: 155 additions & 0 deletions libraries/MCUboot/examples/enableSecurity/enableSecurity.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#include "FlashIAP.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we take the opportunity to add a comment section here that explains the purpose of the sketch, what it does and how it works?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done !

#include "QSPIFBlockDevice.h"
#include "MBRBlockDevice.h"
#include "LittleFileSystem.h"
#include "FATFileSystem.h"
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA)
#include "ecdsa-p256-encrypt-key.h"
#include "ecdsa-p256-signing-key.h"
#else
#error "Security features not available for this board"
#endif

#ifndef CORE_CM7
#error Update the bootloader by uploading the sketch to the M7 core instead of the M4 core.
#endif

#define BOOTLOADER_ADDR (0x8000000)
#define SIGNING_KEY_ADDR (0x8000300)
#define ENCRYPT_KEY_ADDR (0x8000400)
#define ENCRYPT_KEY_SIZE (0x0000100)
#define SIGNING_KEY_SIZE (0x0000100)

mbed::FlashIAP flash;
QSPIFBlockDevice root(QSPI_SO0, QSPI_SO1, QSPI_SO2, QSPI_SO3, QSPI_SCK, QSPI_CS, QSPIF_POLARITY_MODE_1, 40000000);

bool writeKeys = false;
uint32_t bootloader_data_offset = 0x1F000;
uint8_t* bootloader_data = (uint8_t*)(BOOTLOADER_ADDR + bootloader_data_offset);

uint32_t bootloader_identification_offset = 0x2F0;
uint8_t* bootloader_identification = (uint8_t*)(BOOTLOADER_ADDR + bootloader_identification_offset);

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

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

if((currentBootloaderVersion > 24) && (currentBootloaderIdentifier.equals("MCUboot Arduino"))) {
Serial.println("\nThe sketch comes with a set of default keys to evaluate signing and encryption process");
Serial.println("If you load the keys, you will need to upload the future sketches with Security Settings -> Signing + Encryption.");
Serial.println("If you select Security Settings -> None, the sketches will not be executed.");
Serial.println("Do you want to load the keys? Y/[n]");
if (waitResponse()) {
Serial.println("\nPlease notice that loading the keys will enable MCUboot Sketch swap. This will increase the sketch update time after the upload.");
Serial.println("A violet LED will blink until the sketch is ready to run.");
Serial.println("Do you want to proceed loading the default keys? Y/[n]");
writeKeys = waitResponse();
}
}

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

void printProgress(uint32_t offset, uint32_t size, uint32_t threshold, bool reset) {
static int percent_done = 0;
if (reset == true) {
percent_done = 0;
Serial.println("Flashed " + String(percent_done) + "%");
} else {
uint32_t percent_done_new = offset * 100 / size;
if (percent_done_new >= percent_done + threshold) {
percent_done = percent_done_new;
Serial.println("Flashed " + String(percent_done) + "%");
}
}
}

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 setupMCUBootOTAData() {
mbed::MBRBlockDevice ota_data(&root, 2);
mbed::FATFileSystem ota_data_fs("fs");

int err = ota_data_fs.reformat(&ota_data);
if (err) {
Serial.println("Error creating MCUboot files in OTA partition.");
Serial.println("Run QSPIformat.ino sketch to format the QSPI flash and fix the issue.");
}

FILE* fp = fopen("/fs/scratch.bin", "wb");
const int scratch_file_size = 128 * 1024;
const char buffer[128] = {0xFF};
int size = 0;

Serial.println("\nCreating scratch file");
printProgress(size, scratch_file_size, 10, true);
while (size < scratch_file_size) {
int ret = fwrite(buffer, sizeof(buffer), 1, fp);
if (ret != 1) {
Serial.println("Error writing scratch file");
break;
}
size += sizeof(buffer);
printProgress(size, scratch_file_size, 10, false);
}
fclose(fp);

fp = fopen("/fs/update.bin", "wb");
const int update_file_size = 15 * 128 * 1024;
size = 0;

Serial.println("\nCreating update file");
printProgress(size, update_file_size, 10, true);
while (size < update_file_size) {
int ret = fwrite(buffer, sizeof(buffer), 1, fp);
if (ret != 1) {
Serial.println("Error writing scratch file");
break;
}
size += sizeof(buffer);
printProgress(size, update_file_size, 5, false);
}

fclose(fp);
}

void applyUpdate() {
flash.init();
setupMCUBootOTAData();
flash.program(&enc_priv_key, ENCRYPT_KEY_ADDR, ENCRYPT_KEY_SIZE);
flash.program(&ecdsa_pub_key, SIGNING_KEY_ADDR, SIGNING_KEY_SIZE);
Serial.println("Flashed 100%");
flash.deinit();
Serial.println("\nBootloader update complete. It's now safe to reboot or disconnect your board.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer a bootloader update, so we should probably rephrase this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup 💯 i had pushed the change in another branch

}

void loop() {
delay(1000);
}
Loading