Skip to content

Commit

Permalink
Merge pull request #2734 from particle-iot/feature/protected
Browse files Browse the repository at this point in the history
Protected feature
  • Loading branch information
avtolstoy committed Jan 30, 2024
2 parents 691b953 + af691bf commit e0cf88b
Show file tree
Hide file tree
Showing 81 changed files with 1,572 additions and 796 deletions.
4 changes: 2 additions & 2 deletions bootloader/prebootloader/src/rtl872x/part1/sleep_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ void sleepProcess(void) {
SOCPS_SleepInit();
configureSleepWakeupSource(config);

#if PLATFORM_ID == PLATFORM_P2
#if PLATFORM_ID != PLATFORM_TRACKERM
// There is a user LED connected on D7, which is PA27 (SWD-DAT). There is an internal
// pull-up resister on this I/O, which will turn on the user LED when enter the stop/ulp mode.
bool swdEnabled = false;
Expand All @@ -356,7 +356,7 @@ void sleepProcess(void) {

SOCPS_AONTimerCmd(DISABLE);

#if PLATFORM_ID == PLATFORM_P2
#if PLATFORM_ID != PLATFORM_TRACKERM
if (swdEnabled) {
PAD_PullCtrl(27, GPIO_PuPd_UP);
uint32_t temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_SWD_PMUX_EN);
Expand Down
1 change: 1 addition & 0 deletions bootloader/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#endif // HAL_PLATFORM_LED_THEME

#include "timer_hal.h"
#include "bootloader.h"

extern void DFU_Check_Reset();
extern void HAL_DFU_Process();
Expand Down
3 changes: 3 additions & 0 deletions bootloader/src/nRF52840/sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/nRF52840/,pwm
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/nRF52840/,interrupts_hal.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/nRF52840/,dct_hal.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/nRF52840/,nrf_system_error.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/nRF52840/,bootloader.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/nRF52840/,storage_hal.cpp)
CSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/nRF52840/,ota_module_bounds.c)
# FIXME
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/shared/,inflate.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/nRF52840/littlefs/,*.cpp)
Expand Down
44 changes: 42 additions & 2 deletions bootloader/src/nRF52840/usbd_dfu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@
#include "usbd_dfu.h"
#include <cstring>
#include "hal_irq_flag.h"
#include "security_mode.h"

using namespace particle::usbd;
using namespace particle::usbd::dfu;

constexpr const uint8_t DfuClassDriver::msftExtCompatIdOsDescr_[];
constexpr const uint8_t DfuClassDriver::msftExtPropOsDescr_[];

namespace {

const char PROTECTED_MODE_ERROR[] = "Device is in protected mode";

}

DfuClassDriver::DfuClassDriver(Device* dev)
: dev_(dev) {
dev_->registerClass(this);
Expand Down Expand Up @@ -217,6 +224,11 @@ int DfuClassDriver::handleDfuUpload(SetupRequest* req) {
* - wTransferSize: length of the data buffer sent by the host
* - wBlockNumber: value of the wValue parameter
*/
if (security_mode_get(nullptr) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
setError(detail::DfuDeviceStatus::errVENDOR, false /* stall */, PROTECTED_MODE_ERROR);
dev_->setupReply(req, transferBuf_, 0);
break;
}
uintptr_t addr = ((req_.wValue - 2) * USBD_DFU_TRANSFER_SIZE) + address_;
auto ret = currentMal()->read(transferBuf_, addr, req_.wLength);
if (ret != detail::OK) {
Expand Down Expand Up @@ -251,6 +263,9 @@ int DfuClassDriver::handleDfuGetStatus(SetupRequest* req) {
* a pending erase request
*/
setState(detail::dfuDNBUSY);
if (security_mode_get(nullptr) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
setError(detail::DfuDeviceStatus::errVENDOR, false /* stall */, PROTECTED_MODE_ERROR);
}
/* Ask MAL to update bwPollTimeout depending on the current DfuSe command */
currentMal()->getStatus(&status_, dfuseCmd_);
} else {
Expand Down Expand Up @@ -359,18 +374,27 @@ int DfuClassDriver::handleDfuAbort(SetupRequest* req) {
void DfuClassDriver::setState(detail::DfuDeviceState st) {
state_ = st;
status_.bState = state_;
if (state_ != detail::dfuERROR) {
status_.iString = 0;
}
}

void DfuClassDriver::setStatus(detail::DfuDeviceStatus st) {
status_.bStatus = st;
}

void DfuClassDriver::setError(detail::DfuDeviceStatus st, bool stall) {
void DfuClassDriver::setError(detail::DfuDeviceStatus st, bool stall, const char* description) {
setStatus(st);
setState(detail::dfuERROR);
if (stall) {
dev_->setupError(nullptr);
}
if (description) {
status_.iString = (particle::usbd::Device::STRING_IDX_INTERFACE + 1 + USBD_DFU_MAX_CONFIGURATIONS + 1);
strlcpy(errorString_, description, sizeof(errorString_));
} else {
status_.iString = 0;
}
}

DfuMal* DfuClassDriver::currentMal() {
Expand Down Expand Up @@ -444,6 +468,10 @@ int DfuClassDriver::inDone(uint8_t ep, unsigned status) {
}
case detail::DFUSE_COMMAND_ERASE: {
if (req_.wLength == sizeof(uint32_t) + 1) {
if (security_mode_get(nullptr) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
setError(detail::DfuDeviceStatus::errVENDOR, false /* stall */, PROTECTED_MODE_ERROR);
break;
}
uintptr_t addr = *((uint32_t*)(transferBuf_ + 1));
auto ret = currentMal()->erase(addr, 0);
if (ret != detail::OK) {
Expand Down Expand Up @@ -477,6 +505,10 @@ int DfuClassDriver::inDone(uint8_t ep, unsigned status) {
* - wTransferSize: length of the data buffer sent by the host
* - wBlockNumber: value of the wValue parameter
*/
if (security_mode_get(nullptr) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
setError(detail::DfuDeviceStatus::errVENDOR, false /* stall */, PROTECTED_MODE_ERROR);
break;
}
uintptr_t addr = ((req_.wValue - 2) * USBD_DFU_TRANSFER_SIZE) + address_;
auto ret = currentMal()->write(transferBuf_, addr, req_.wLength);
if (ret != detail::OK) {
Expand Down Expand Up @@ -510,8 +542,16 @@ const uint8_t* DfuClassDriver::getConfigurationDescriptor(uint16_t* length) {

const uint8_t* DfuClassDriver::getStringDescriptor(unsigned index, uint16_t* length, bool* conv) {
if (index >= (particle::usbd::Device::STRING_IDX_INTERFACE + 1) &&
index <= (particle::usbd::Device::STRING_IDX_INTERFACE + 1 + USBD_DFU_MAX_CONFIGURATIONS)) {
index <= (particle::usbd::Device::STRING_IDX_INTERFACE + 1 + USBD_DFU_MAX_CONFIGURATIONS + 1)) {
const unsigned idx = index - (particle::usbd::Device::STRING_IDX_INTERFACE + 1);
if (idx == (USBD_DFU_MAX_CONFIGURATIONS + 1)) {
*conv = true;
// Error string
if (errorString_) {
*length = strlen(errorString_);
}
return (const uint8_t*)errorString_;
}
auto m = mal_[idx];
if (m) {
*conv = true;
Expand Down
4 changes: 3 additions & 1 deletion bootloader/src/nRF52840/usbd_dfu.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "usbd_device.h"

#include "usbd_wcid.h"
#include <climits>

#ifndef USBD_DFU_MAX_CONFIGURATIONS
#define USBD_DFU_MAX_CONFIGURATIONS (3)
Expand Down Expand Up @@ -229,7 +230,7 @@ class DfuClassDriver : public particle::usbd::ClassDriver {
void reset();
void setState(detail::DfuDeviceState st);
void setStatus(detail::DfuDeviceStatus st);
void setError(detail::DfuDeviceStatus st, bool stall = true);
void setError(detail::DfuDeviceStatus st, bool stall = true, const char* description = nullptr);
DfuMal* currentMal();

private:
Expand Down Expand Up @@ -298,6 +299,7 @@ class DfuClassDriver : public particle::usbd::ClassDriver {
#endif
USBD_DFU_FUNCTIONAL_DESCRIPTOR()
};
char errorString_[UCHAR_MAX] = {};
};

} } } /* namespace particle::usbd::dfu */
Expand Down
6 changes: 3 additions & 3 deletions bootloader/src/nRF52840/usbd_dfu_mal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ int InternalFlashMal::getStatus(detail::DfuGetStatus* status, dfu::detail::Dfuse
}

const char* InternalFlashMal::getString() {
return INTERNAL_FLASH_IF_STRING;
return security_mode_get(nullptr) != MODULE_INFO_SECURITY_MODE_PROTECTED ? INTERNAL_FLASH_IF_STRING : INTERNAL_FLASH_IF_STRING_PROT;
}

DctMal::DctMal()
Expand Down Expand Up @@ -168,7 +168,7 @@ int DctMal::getStatus(detail::DfuGetStatus* status, dfu::detail::DfuseCommand cm
}

const char* DctMal::getString() {
return DCT_IF_STRING;
return security_mode_get(nullptr) != MODULE_INFO_SECURITY_MODE_PROTECTED ? DCT_IF_STRING : DCT_IF_STRING_PROT;
}

ExternalFlashMal::ExternalFlashMal()
Expand Down Expand Up @@ -241,5 +241,5 @@ int ExternalFlashMal::getStatus(detail::DfuGetStatus* status, dfu::detail::Dfuse
}

const char* ExternalFlashMal::getString() {
return EXTERNAL_FLASH_IF_STRING;
return security_mode_get(nullptr) != MODULE_INFO_SECURITY_MODE_PROTECTED ? EXTERNAL_FLASH_IF_STRING : EXTERNAL_FLASH_IF_STRING_PROT;
}
12 changes: 8 additions & 4 deletions bootloader/src/nRF52840/usbd_dfu_mal.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,23 @@

#define INTERNAL_FLASH_START_ADD 0x00000000
#define INTERNAL_FLASH_END_ADDR 0x00100000
#define INTERNAL_FLASH_IF_STRING "@Internal Flash /0x00000000/1*004Ka,47*004Kg,192*004Kg,4*004Kg,4*004Kg,8*004Ka";
#define INTERNAL_FLASH_IF_STRING "@Internal Flash /0x00000000/1*004Ka,47*004Kg,192*004Kg,4*004Kg,4*004Kg,8*004Ka"
#define INTERNAL_FLASH_IF_STRING_PROT "@Internal Flash /0x00000000/1*004Kb,47*004Kb,192*004Kb,4*004Kb,4*004Kb,8*004Kb"

#define DCT_START_ADD 0x00000000
#define DCT_END_ADDR 0x00004000
#define DCT_IF_STRING "@DCT Flash /0x00000000/1*016Ke";
#define DCT_IF_STRING "@DCT Flash /0x00000000/1*016Ke"
#define DCT_IF_STRING_PROT "@DCT Flash /0x00000000/1*016Kb"

#define EXTERNAL_FLASH_START_ADD 0x00000000
#if PLATFORM_ID == PLATFORM_B5SOM || PLATFORM_ID == PLATFORM_TRACKER || PLATFORM_ID == PLATFORM_ESOMX
#define EXTERNAL_FLASH_END_ADDR 0x00800000
#define EXTERNAL_FLASH_IF_STRING "@External Flash /0x80000000/2048*004Kg";
#define EXTERNAL_FLASH_IF_STRING "@External Flash /0x80000000/2048*004Kg"
#define EXTERNAL_FLASH_IF_STRING_PROT "@External Flash /0x80000000/2048*004Kb"
#else
#define EXTERNAL_FLASH_END_ADDR 0x00400000
#define EXTERNAL_FLASH_IF_STRING "@External Flash /0x80000000/1024*004Kg";
#define EXTERNAL_FLASH_IF_STRING "@External Flash /0x80000000/1024*004Kg"
#define EXTERNAL_FLASH_IF_STRING_PROT "@External Flash /0x80000000/1024*004Kb"
#endif


Expand Down
4 changes: 4 additions & 0 deletions bootloader/src/rtl872x/sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ CSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/rtl872x/littlef
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/shared/,filesystem.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/rtl872x/,usbd_device.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/rtl872x/,usbd_driver.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/rtl872x/,bootloader.cpp)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/rtl872x/,storage_hal.cpp)
CSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/rtl872x/,ota_module_bounds.c)
CPPSRC += $(call target_files,$(BOOTLOADER_MODULE_PATH)/../hal/src/rtl872x/,efuse.cpp)

LDFLAGS += -T$(BOOTLOADER_SRC_PATH)/linker.ld
LINKER_DEPS += $(BOOTLOADER_SRC_PATH)/linker.ld
39 changes: 37 additions & 2 deletions bootloader/src/rtl872x/usbd_dfu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,20 @@
#include <cstring>
#include "hal_irq_flag.h"
#include <algorithm>
#include "security_mode.h"

using namespace particle::usbd;
using namespace particle::usbd::dfu;

constexpr const uint8_t DfuClassDriver::msftExtCompatIdOsDescr_[];
constexpr const uint8_t DfuClassDriver::msftExtPropOsDescr_[];

namespace {

const char PROTECTED_MODE_ERROR[] = "Device is in protected mode";

}

DfuClassDriver::DfuClassDriver(Device* dev)
: ClassDriver(dev) {
}
Expand Down Expand Up @@ -218,6 +225,11 @@ int DfuClassDriver::handleDfuUpload(SetupRequest* req) {
* - wTransferSize: length of the data buffer sent by the host
* - wBlockNumber: value of the wValue parameter
*/
if (security_mode_get(nullptr) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
setError(detail::DfuDeviceStatus::errVENDOR, false /* stall */, PROTECTED_MODE_ERROR);
dev_->setupReply(req, transferBuf_, 0);
break;
}
uintptr_t addr = ((req_.wValue - 2) * USBD_DFU_TRANSFER_SIZE) + address_;
auto ret = currentMal()->read(transferBuf_, addr, req_.wLength);
if (ret != detail::OK) {
Expand Down Expand Up @@ -252,6 +264,9 @@ int DfuClassDriver::handleDfuGetStatus(SetupRequest* req) {
* a pending erase request
*/
setState(detail::dfuDNBUSY);
if (security_mode_get(nullptr) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
setError(detail::DfuDeviceStatus::errVENDOR, false /* stall */, PROTECTED_MODE_ERROR);
}
/* Ask MAL to update bwPollTimeout depending on the current DfuSe command */
currentMal()->getStatus(&status_, dfuseCmd_);
} else {
Expand Down Expand Up @@ -360,18 +375,27 @@ int DfuClassDriver::handleDfuAbort(SetupRequest* req) {
void DfuClassDriver::setState(detail::DfuDeviceState st) {
state_ = st;
status_.bState = state_;
if (state_ != detail::dfuERROR) {
status_.iString = 0;
}
}

void DfuClassDriver::setStatus(detail::DfuDeviceStatus st) {
status_.bStatus = st;
}

void DfuClassDriver::setError(detail::DfuDeviceStatus st, bool stall) {
void DfuClassDriver::setError(detail::DfuDeviceStatus st, bool stall, const char* description) {
setStatus(st);
setState(detail::dfuERROR);
if (stall) {
dev_->setupError(nullptr);
}
if (description) {
status_.iString = stringBase_ + HAL_PLATFORM_USB_DFU_INTERFACES;
strlcpy(errorString_, description, sizeof(errorString_));
} else {
status_.iString = 0;
}
}

DfuMal* DfuClassDriver::currentMal() {
Expand Down Expand Up @@ -429,6 +453,10 @@ int DfuClassDriver::dataIn(unsigned ep, particle::usbd::EndpointEvent ev, size_t
}
case detail::DFUSE_COMMAND_ERASE: {
if (req_.wLength == sizeof(uint32_t) + 1) {
if (security_mode_get(nullptr) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
setError(detail::DfuDeviceStatus::errVENDOR, false /* stall */, PROTECTED_MODE_ERROR);
break;
}
uintptr_t addr = *((uint32_t*)(transferBuf_ + 1));
auto ret = currentMal()->erase(addr, 0);
if (ret != detail::OK) {
Expand Down Expand Up @@ -462,6 +490,10 @@ int DfuClassDriver::dataIn(unsigned ep, particle::usbd::EndpointEvent ev, size_t
* - wTransferSize: length of the data buffer sent by the host
* - wBlockNumber: value of the wValue parameter
*/
if (security_mode_get(nullptr) == MODULE_INFO_SECURITY_MODE_PROTECTED) {
setError(detail::DfuDeviceStatus::errVENDOR, false /* stall */, PROTECTED_MODE_ERROR);
break;
}
uintptr_t addr = ((req_.wValue - 2) * USBD_DFU_TRANSFER_SIZE) + address_;
auto ret = currentMal()->write(transferBuf_, addr, req_.wLength);
if (ret != detail::OK) {
Expand Down Expand Up @@ -509,6 +541,9 @@ int DfuClassDriver::getString(unsigned id, uint16_t langId, uint8_t* buf, size_t
return -1;
}
const unsigned idx = id - stringBase_;
if (id == status_.iString && status_.iString && state_ == dfu::detail::DfuDeviceState::dfuERROR && strlen(errorString_) ) {
return dev_->getUnicodeString(errorString_, strlen(errorString_), buf, length);
}
if (idx > HAL_PLATFORM_USB_DFU_INTERFACES) {
return -1;
}
Expand All @@ -528,7 +563,7 @@ int DfuClassDriver::getNumInterfaces() const {
}

int DfuClassDriver::getNumStrings() const {
return HAL_PLATFORM_USB_DFU_INTERFACES;
return HAL_PLATFORM_USB_DFU_INTERFACES + 1 /* error string */;
}

unsigned DfuClassDriver::getEndpointMask() const {
Expand Down
4 changes: 3 additions & 1 deletion bootloader/src/rtl872x/usbd_dfu.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "usbd_device.h"
#include "usbd_wcid.h"
#include "hal_platform.h"
#include <climits>

#ifndef USBD_DFU_TRANSFER_SIZE
#define USBD_DFU_TRANSFER_SIZE (4096)
Expand Down Expand Up @@ -227,7 +228,7 @@ class DfuClassDriver : public particle::usbd::ClassDriver {
void reset();
void setState(detail::DfuDeviceState st);
void setStatus(detail::DfuDeviceStatus st);
void setError(detail::DfuDeviceStatus st, bool stall = true);
void setError(detail::DfuDeviceStatus st, bool stall = true, const char* description = nullptr);
DfuMal* currentMal();

private:
Expand Down Expand Up @@ -295,6 +296,7 @@ class DfuClassDriver : public particle::usbd::ClassDriver {
#endif
USBD_DFU_FUNCTIONAL_DESCRIPTOR()
};
char errorString_[UCHAR_MAX] = {};
};

} } } /* namespace particle::usbd::dfu */
Expand Down
5 changes: 3 additions & 2 deletions bootloader/src/rtl872x/usbd_dfu_mal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "flash_hal.h"
#include "dct.h"
#include "flash_mal.h"
#include "security_mode.h"

using namespace particle::usbd::dfu::mal;

Expand Down Expand Up @@ -94,7 +95,7 @@ int InternalFlashMal::getStatus(detail::DfuGetStatus* status, dfu::detail::Dfuse
}

const char* InternalFlashMal::getString() {
return INTERNAL_FLASH_IF_STRING;
return security_mode_get(nullptr) != MODULE_INFO_SECURITY_MODE_PROTECTED ? INTERNAL_FLASH_IF_STRING : INTERNAL_FLASH_IF_STRING_PROT;
}

DctMal::DctMal()
Expand Down Expand Up @@ -149,5 +150,5 @@ int DctMal::getStatus(detail::DfuGetStatus* status, dfu::detail::DfuseCommand cm
}

const char* DctMal::getString() {
return DCT_IF_STRING;
return security_mode_get(nullptr) != MODULE_INFO_SECURITY_MODE_PROTECTED ? DCT_IF_STRING : DCT_IF_STRING_PROT;
}

0 comments on commit e0cf88b

Please sign in to comment.