From 277a9651a4e98a8b0dd8bf95935e058f73364914 Mon Sep 17 00:00:00 2001 From: ksmith3036 <44052735+ksmith3036@users.noreply.github.com> Date: Sun, 3 Jan 2021 11:30:53 +0100 Subject: [PATCH 1/2] When Secure Bit is set: Prevent tries of partial flashing using Write word, Half words or Byte combinations, by flashing entire Arduino sketch. --- bootloaders/zero/sam_ba_monitor.c | 45 ++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/bootloaders/zero/sam_ba_monitor.c b/bootloaders/zero/sam_ba_monitor.c index 619d1334b..0c94d6cc7 100644 --- a/bootloaders/zero/sam_ba_monitor.c +++ b/bootloaders/zero/sam_ba_monitor.c @@ -362,15 +362,54 @@ static void sam_ba_monitor_loop(void) } else if (command == 'O') // write byte { - *ptr_data = (char) current_number; + if (b_security_enabled && (uint16_t *)ptr_data == &NVMCTRL->CTRLA.reg && (current_number & NVMCTRL_CTRLA_CMD_Msk) == NVMCTRL_CTRLA_CMD_ER) + { + // NVM Erase Row command received in secure mode. + // To mitigate that an attacker might not use the ordinary BOSSA method of erasing flash before programming, + // always erase flash, if it hasn't been done already. + if (erased_from != 0x2000) + { + eraseFlash(0x2000); + } + } + else + { + *ptr_data = (char) current_number; + } } else if (command == 'H') // Write half word { - *((uint16_t *) ptr_data) = (uint16_t) current_number; + if (b_security_enabled && (uint16_t *)ptr_data == &NVMCTRL->CTRLA.reg && (current_number & NVMCTRL_CTRLA_CMD_Msk) == NVMCTRL_CTRLA_CMD_ER) + { + // NVM Erase Row command received in secure mode. + // To mitigate that an attacker might not use the ordinary BOSSA method of erasing flash before programming, + // always erase flash, if it hasn't been done already. + if (erased_from != 0x2000) + { + eraseFlash(0x2000); + } + } + else + { + *((uint16_t *) ptr_data) = (uint16_t) current_number; + } } else if (command == 'W') // Write word { - *((int *) ptr_data) = current_number; + if (b_security_enabled && (uint16_t *)ptr_data == &NVMCTRL->CTRLA.reg && (current_number & NVMCTRL_CTRLA_CMD_Msk) == NVMCTRL_CTRLA_CMD_ER) + { + // NVM Erase Row command received in secure mode. + // To mitigate that an attacker might not use the ordinary BOSSA method of erasing flash before programming, + // always erase flash, if it hasn't been done already. + if (erased_from != 0x2000) + { + eraseFlash(0x2000); + } + } + else + { + *((int *) ptr_data) = current_number; + } } else if (command == 'o') // Read byte { From ae22762119a650afb086640097fa5c62b2f1abac Mon Sep 17 00:00:00 2001 From: ksmith3036 <44052735+ksmith3036@users.noreply.github.com> Date: Sun, 3 Jan 2021 11:31:33 +0100 Subject: [PATCH 2/2] Combine full version information into one const string in source code to optimize bootloader size, to make the bootloader for MKR VIDOR 4000 less than 8 KByte in size. --- bootloaders/zero/sam_ba_monitor.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/bootloaders/zero/sam_ba_monitor.c b/bootloaders/zero/sam_ba_monitor.c index 0c94d6cc7..fcd4f392d 100644 --- a/bootloaders/zero/sam_ba_monitor.c +++ b/bootloaders/zero/sam_ba_monitor.c @@ -29,9 +29,9 @@ #include "board_driver_led.h" #include -const char RomBOOT_Version[] = SAM_BA_VERSION; // X = Chip Erase, Y = Write Buffer, Z = Checksum Buffer, P = Secure Bit Aware -const char RomBOOT_ExtendedCapabilities[] = "[Arduino:XYZP]"; +#define ROMBOOT_EXTENDEDCAPABILITIES "[Arduino:XYZP]" +const char ROMBoot_VersionInformation[] = "v" SAM_BA_VERSION " " ROMBOOT_EXTENDEDCAPABILITIES " " __DATE__ " " __TIME__ "\n\r"; /* Provides one common interface to handle both USART and USB-CDC */ typedef struct @@ -485,12 +485,7 @@ static void sam_ba_monitor_loop(void) } else if (command == 'V') // Read version information { - sam_ba_putdata( ptr_monitor_if, "v", 1); - sam_ba_putdata( ptr_monitor_if, (uint8_t *) RomBOOT_Version, strlen(RomBOOT_Version)); - sam_ba_putdata( ptr_monitor_if, " ", 1); - sam_ba_putdata( ptr_monitor_if, (uint8_t *) RomBOOT_ExtendedCapabilities, strlen(RomBOOT_ExtendedCapabilities)); - ptr = (uint8_t*) &(" " __DATE__ " " __TIME__ "\n\r"); - sam_ba_putdata( ptr_monitor_if, ptr, strlen(ptr)); + sam_ba_putdata( ptr_monitor_if, ROMBoot_VersionInformation, sizeof(ROMBoot_VersionInformation) - 1); } else if (command == 'X') // Erase flash {