Headline
CVE-2022-24936: gecko_sdk/platform/bootloader/core/btl_bootload.c at 2e82050dc8823c9fe0e8908c1b2666fb83056230 · SiliconLabs/gecko_sdk
Out-of-Bounds error in GBL parser in Silicon Labs Gecko Bootloader version 4.0.1 and earlier allows attacker to overwrite flash Sign key and OTA decryption key via malicious bootloader upgrade.
Dec 15, 2021
1
/***************************************************************************//**
3
* @brief Bootloading functionality for the Silicon Labs bootloader
4
*******************************************************************************
6
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
7
*******************************************************************************
9
* The licensor of this software is Silicon Laboratories Inc. Your use of this
10
* software is governed by the terms of Silicon Labs Master Software License
11
* Agreement (MSLA) available at
12
* www.silabs.com/about-us/legal/master-software-license-agreement. This
13
* software is distributed to you in Source Code format and is governed by the
14
* sections of the MSLA applicable to Source Code.
16
******************************************************************************/
17
#include “config/btl_config.h”
19
#include “btl_bootload.h”
20
#include “btl_reset.h”
23
#if defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
30
#include “api/btl_interface.h”
31
#include “api/application_properties.h”
34
#include “parser/gbl/btl_gbl_parser.h”
36
// Security algorithms
37
#include “security/btl_security_types.h”
38
#include “security/btl_security_ecdsa.h”
39
#include “security/btl_crc32.h”
40
#include “security/btl_security_tokens.h”
43
#include “core/flash/btl_internal_flash.h”
46
#include “debug/btl_debug.h”
52
// Silence MISRA warning disallowing statements without side effects
53
#pragma diag_suppress=Pm049
Mar 10, 2022
54
// Silence MISRA warning disallowing access to volatile object in right-hand operand of || operator
55
#pragma diag_suppress=Pm026
Dec 15, 2021
61
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
62
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80) || defined(MAIN_BOOTLOADER_IN_MAIN_FLASH)
63
#error “Rollback protection not supported”
65
#endif // defined(BOOTLOADER_ROLLBACK_PROTECTION)
67
#if defined(BOOTLOADER_SUPPORT_CERTIFICATES) && (BOOTLOADER_SUPPORT_CERTIFICATES == 1)
68
#if !defined(_SILICON_LABS_32B_SERIES_2)
69
#error “Certificate not supported”
71
#endif // defined(BOOTLOADER_SUPPORT_CERTIFICATES)
73
// --------------------------------
74
// Local type declarations
75
static bool bootload_verifySecureBoot(uint32_t startAddress);
77
static void flashData(uint32_t address,
81
static bool getSignatureX(ApplicationProperties_t *appProperties,
82
uint32_t *appSignatureX);
84
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
85
static bool checkResetMagic(void);
86
static bool checkMaxVersionMagic(void);
87
static uint32_t getHighestApplicationVersionSeen(void);
90
// --------------------------------
93
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
94
#define SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY 6UL
95
#define SL_GBL_APPLICATION_VERSION_MAX_MAGIC 0x1234DCBAUL
96
#define SL_GBL_APPLICATION_VERSION_RESET_MAGIC 0x5839FBACUL
97
#define SL_GBL_UINT32_MAX_NUMBER 0xFFFFFFFFUL
100
// --------------------------------
103
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
104
static bool checkMaxVersionMagic(void)
106
uint32_t *versionMaxMagicPtr = bootload_getApplicationVersionStoragePtr(SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY);
107
if (*versionMaxMagicPtr == SL_GBL_APPLICATION_VERSION_MAX_MAGIC) {
113
static bool checkResetMagic(void)
115
uint32_t *versionResetMagicPtr = bootload_getApplicationVersionStoragePtr(SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY + 1UL);
116
if (*versionResetMagicPtr == SL_GBL_APPLICATION_VERSION_RESET_MAGIC) {
122
static uint32_t getHighestApplicationVersionSeen(void)
124
uint32_t *appVersionStoragePtr = bootload_getApplicationVersionStoragePtr(SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY);
125
if (checkMaxVersionMagic()) {
126
return SL_GBL_UINT32_MAX_NUMBER;
129
for (uint32_t i = 0UL; i < SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY; i++) {
130
++appVersionStoragePtr;
131
if (*appVersionStoragePtr != SL_GBL_UINT32_MAX_NUMBER) {
132
return *appVersionStoragePtr;
136
return PARSER_APPLICATION_MINIMUM_VERSION_VALID;
140
static void flashData(uint32_t address,
144
const uint32_t pageSize = (uint32_t)FLASH_PAGE_SIZE;
146
// Erase the page if write starts at a page boundary
147
if (address % pageSize == 0UL) {
148
flash_erasePage(address);
151
// Erase all pages that start inside the write range
152
for (uint32_t pageAddress = (address + pageSize) & ~(pageSize - 1UL);
153
pageAddress < (address + length);
154
pageAddress += pageSize) {
155
flash_erasePage(pageAddress);
158
BTL_DEBUG_PRINT("F ");
159
BTL_DEBUG_PRINT_WORD_HEX(length);
160
BTL_DEBUG_PRINT(" to ");
161
BTL_DEBUG_PRINT_WORD_HEX(address);
162
BTL_DEBUG_PRINT_LF();
164
flash_writeBuffer_dma(address, data, length, SL_GBL_MSC_LDMA_CHANNEL);
167
static bool getSignatureX(ApplicationProperties_t *appProperties, uint32_t *appSignatureX)
169
// Check if app properties struct or legacy direct signature pointer
170
if (bootload_checkApplicationPropertiesMagic(appProperties)) {
171
if (appProperties->signatureType != APPLICATION_SIGNATURE_ECDSA_P256) {
172
// Application signature isn’t ECDSA, fail early
173
BTL_DEBUG_PRINTLN(“Wrong s type”);
176
// Compatibility check of the application properties struct.
177
if (!bootload_checkApplicationPropertiesVersion(appProperties)) {
180
*appSignatureX = appProperties->signatureLocation;
182
*appSignatureX = (uint32_t)appProperties;
187
static bool bootload_verifySecureBoot(uint32_t startAddress)
189
volatile int32_t retVal = BOOTLOADER_ERROR_SECURITY_REJECTED;
190
Sha256Context_t shaState;
192
BareBootTable_t *appStart = (BareBootTable_t *)startAddress;
193
uint32_t appProps = (uint32_t)appStart->signature;
194
uint32_t appSignatureX, appSignatureY;
195
ApplicationProperties_t *appProperties =
196
(ApplicationProperties_t *)(appProps);
198
if (!bootload_checkApplicationPropertiesMagic(appProperties)) {
201
if (!bootload_checkApplicationPropertiesVersion(appProperties)) {
205
#if !defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
206
if (PARSER_REQUIRE_ANTI_ROLLBACK_PROTECTION) {
207
if (!bootload_verifyApplicationVersion(appProperties->app.version, true)) {
213
#if defined(_SILICON_LABS_32B_SERIES_2)
214
// Access word 13 to read sl_app_properties of the bootloader.
215
ApplicationProperties_t *blProperties =
216
(ApplicationProperties_t *)(*(uint32_t *)(BTL_MAIN_STAGE_BASE + 52UL));
217
if (!bootload_checkApplicationPropertiesMagic(blProperties)) {
220
#if !defined(MAIN_BOOTLOADER_TEST)
221
if ((uint32_t)blProperties > ((uint32_t)mainBootloaderTable->startOfAppSpace - sizeof(ApplicationProperties_t))) {
222
// Make sure that this pointer is within the bootloader space.
227
bool gotCert = false;
228
if (!bootload_verifyApplicationCertificate(appProperties, &gotCert)) {
233
if (!getSignatureX(appProperties, &appSignatureX)) {
237
// Check that signature is in application flash
238
if ((appSignatureX < (uint32_t)(mainBootloaderTable->startOfAppSpace))
239
|| (appSignatureX < startAddress)
240
|| (appSignatureX > (FLASH_BASE + FLASH_SIZE))) {
241
BTL_DEBUG_PRINTLN(“No sign”);
245
// SHA-256 of the entire application (startAddress until signature)
246
btl_initSha256(&shaState);
247
btl_updateSha256(&shaState,
248
(const uint8_t*)startAddress,
249
appSignatureX - startAddress);
250
btl_finalizeSha256(&shaState);
252
appSignatureY = appSignatureX + 32UL;
253
#if defined(_SILICON_LABS_32B_SERIES_2)
254
if (PARSER_REQUIRE_CERTIFICATE_AUTHENTICITY) {
256
// Application certificate is already verified to be valid at this point.
257
// Authenticate the application using the certificate of the application.
258
retVal = btl_verifyEcdsaP256r1(shaState.sha,
259
(uint8_t*)appSignatureX,
260
(uint8_t*)appSignatureY,
261
&(appProperties->cert->key[0]),
262
&(appProperties->cert->key[32]));
264
// Application is directly signed + cert on app is not required.
265
// Authenticate the application using the certificate of the bootloader.
266
retVal = btl_verifyEcdsaP256r1(shaState.sha,
267
(uint8_t*)appSignatureX,
268
(uint8_t*)appSignatureY,
269
&(blProperties->cert->key[0]),
270
&(blProperties->cert->key[32]));
273
// Use “lock bits” key or platform key to authenticate the application.
274
retVal = btl_verifyEcdsaP256r1(shaState.sha,
275
(uint8_t*)appSignatureX,
276
(uint8_t*)appSignatureY,
277
btl_getSignedBootloaderKeyXPtr(),
278
btl_getSignedBootloaderKeyYPtr());
281
retVal = btl_verifyEcdsaP256r1(shaState.sha,
282
(uint8_t*)appSignatureX,
283
(uint8_t*)appSignatureY,
284
btl_getSignedBootloaderKeyXPtr(),
285
btl_getSignedBootloaderKeyYPtr());
287
if (retVal == BOOTLOADER_OK) {
290
BTL_DEBUG_PRINTLN(“Inv sign”);
295
// --------------------------------
299
void bootload_applicationCallback(uint32_t address,
305
// Check if addresses to write to are within writeable space
306
if ((address < (uint32_t)(mainBootloaderTable->startOfAppSpace))
307
|| ((address + length)
308
> (uint32_t)(mainBootloaderTable->endOfAppSpace))) {
309
BTL_DEBUG_PRINT(“OOB 0x”);
310
BTL_DEBUG_PRINT_WORD_HEX(address);
311
BTL_DEBUG_PRINT_LF();
315
flashData(address, data, length);
318
void bootload_bootloaderCallback(uint32_t offset,
325
#if defined(BOOTLOADER_HAS_FIRST_STAGE)
326
if (firstBootloaderTable->header.type != BOOTLOADER_MAGIC_FIRST_STAGE) {
327
// No first stage present
Mar 10, 2022
332
// Do not allow overwriting the last page of main flash if it coincides with
333
// the “lock bits” page.
334
#if defined(LOCKBITS_BASE) \
335
&& (LOCKBITS_BASE != (FLASH_BASE + FLASH_SIZE - FLASH_PAGE_SIZE))
336
const uint32_t max_address = FLASH_BASE + FLASH_SIZE;
338
const uint32_t max_address = FLASH_BASE + FLASH_SIZE - FLASH_PAGE_SIZE;
340
volatile uint32_t address = BTL_UPGRADE_LOCATION + offset;
343
// i) if NOT (BTL_UPGRADE_LOCATION <= address < max_address),
344
// with integer overflow check for address
345
if ((offset > (uint32_t) (UINT32_MAX - BTL_UPGRADE_LOCATION))
346
|| (address >= max_address)) {
347
BTL_DEBUG_PRINT(“OOB, address not in allowed range; (address) 0x”);
348
BTL_DEBUG_PRINT_WORD_HEX(address);
349
BTL_DEBUG_PRINT_LF();
352
// ii) Semantically equivalent to (address + length > max_address),
353
// but without the risk of integer overflow (or underflow, because of (i))
354
if (length > (uint32_t) (max_address - address)) {
355
BTL_DEBUG_PRINT(“OOB, length too large; (address) 0x”);
Dec 15, 2021
356
BTL_DEBUG_PRINT_WORD_HEX(address);
Mar 10, 2022
357
BTL_DEBUG_PRINT(“, (length) 0x”);
358
BTL_DEBUG_PRINT_WORD_HEX(length);
Dec 15, 2021
359
BTL_DEBUG_PRINT_LF();
363
// Erase first page of app if this is the first write and
364
// if the bootloader upgrade location overlaps with the application.
365
// This ensures that application is not misinterpreted as valid when
366
// bootloader upgrade has started
368
if (BTL_UPGRADE_LOCATION < (uint32_t)(mainBootloaderTable->endOfAppSpace)) {
369
flash_erasePage((uint32_t)(mainBootloaderTable->startOfAppSpace));
373
flashData(address, data, length);
376
bool bootload_checkApplicationPropertiesMagic(void *appProperties)
378
if (appProperties == NULL) {
382
#if (FLASH_BASE > 0x0UL)
383
if ((uint32_t)appProperties < FLASH_BASE) {
388
uint8_t magicRev[16U] = APPLICATION_PROPERTIES_REVERSED;
389
uint8_t *magic = (uint8_t *)appProperties;
391
for (size_t i = 0U; i < 16U; i++) {
392
if (magicRev[15U - i] != magic[i]) {
400
bool bootload_checkApplicationPropertiesVersion(void *appProperties)
402
ApplicationProperties_t *appProp = (ApplicationProperties_t *)appProperties;
403
// Compatibility check of the application properties struct.
404
if (((appProp->structVersion & APPLICATION_PROPERTIES_VERSION_MAJOR_MASK)
405
>> APPLICATION_PROPERTIES_VERSION_MAJOR_SHIFT)
406
> (uint32_t)APPLICATION_PROPERTIES_VERSION_MAJOR) {
412
bool bootload_verifyApplication(uint32_t startAddress)
414
BareBootTable_t *appStart = (BareBootTable_t *)startAddress;
415
uint32_t appSp = (uint32_t)appStart->stackTop;
416
uint32_t appPc = (uint32_t)appStart->resetVector;
417
uint32_t appProps = (uint32_t)appStart->signature;
419
// Check that SP points to RAM
420
if ((appSp < SRAM_BASE) || (appSp > (SRAM_BASE + SRAM_SIZE))) {
421
BTL_DEBUG_PRINTLN(“SP n/i RAM”);
425
// Check that PC points to application flash
426
if ((appPc < (uint32_t)mainBootloaderTable->startOfAppSpace)
427
|| (appPc > (FLASH_BASE + FLASH_SIZE))) {
428
BTL_DEBUG_PRINTLN(“PC n/i flash”);
432
ApplicationProperties_t *appProperties =
433
(ApplicationProperties_t *)(appProps);
435
// Application properties pointer can take on many possible values:
437
// 0xFFFFFFFF - Likely unused part of AAT
438
// [FLASH_BASE, FLASH_SIZE] - Likely one of three things:
439
// - Pointer to Reset_Handler (app without app properties)
440
// - Pointer to ApplicationProperties_t
441
// - Pointer to ECDSA signature (legacy direct solution)
443
if ((appProps < ((uint32_t)mainBootloaderTable->startOfAppSpace + 64UL))
444
|| (appProps > (FLASH_BASE + FLASH_SIZE))) {
445
// Application properties pointer does not point inside flash (is not valid)
446
if (BOOTLOADER_ENFORCE_SECURE_BOOT) {
447
// Secure boot is enforced. Either an app properties struct or a direct
448
// pointer to the signature is required. An address outside main flash
449
// is not valid for either case.
450
BTL_DEBUG_PRINTLN(“AP n/i flash”);
453
// Secure boot is not enforced, we have to assume app is valid
454
BTL_DEBUG_PRINTLN(“No SB, assume valid”);
457
} else if (BOOTLOADER_ENFORCE_SECURE_BOOT) {
458
// Secure boot is enforced, attempt to verify secure boot signature
459
BTL_DEBUG_PRINTLN(“Secure boot 1”);
460
return bootload_verifySecureBoot(startAddress);
461
} else if (bootload_checkApplicationPropertiesMagic(appProperties)) {
462
if (!bootload_checkApplicationPropertiesVersion(appProperties)) {
465
// Application properties pointer is valid, decide what action to take
466
// based on signature type
467
if (appProperties->signatureType == APPLICATION_SIGNATURE_NONE) {
468
// No signature, app has to be assumed valid
469
BTL_DEBUG_PRINTLN(“No signature, assume valid”);
471
} else if (appProperties->signatureType == APPLICATION_SIGNATURE_CRC32) {
472
#ifdef BTL_LIB_NO_SUPPORT_CRC32_SIGNATURE
473
// Don’t support CRC32, app has to be assumed valid
474
BTL_DEBUG_PRINTLN(“CRC not supported, assume valid”);
477
uint32_t crc = btl_crc32Stream(
478
(void *)startAddress,
479
appProperties->signatureLocation + 4UL - startAddress,
481
if (crc == BTL_CRC32_END) {
482
BTL_DEBUG_PRINTLN(“CRC success”);
489
// Default to secure boot check
490
BTL_DEBUG_PRINTLN(“Secure boot 2”);
491
return bootload_verifySecureBoot(startAddress);
494
// Application properties pointer points into flash, but doesn’t point to
495
// an application properties struct.
496
// Secure boot is not enforced (checked above), assume that this is a
497
// pointer to the Reset_Handler and that the app is valid
498
BTL_DEBUG_PRINTLN(“No AP, assume valid”);
503
uint32_t bootload_getApplicationVersionStorageCapacity(void)
505
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
506
return SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY;
512
uint32_t* bootload_getApplicationVersionStoragePtr(uint32_t index)
514
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
515
uint32_t endOfBLpage = BTL_FIRST_STAGE_BASE + BTL_FIRST_STAGE_SIZE + BTL_MAIN_STAGE_MAX_SIZE;
516
uint32_t *appVersionStoragePtr = (uint32_t*)endOfBLpage - (index + 1UL);
517
return appVersionStoragePtr;
524
bool bootload_storeApplicationVersion(uint32_t startAddress)
526
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
527
BareBootTable_t *appStart = (BareBootTable_t *)startAddress;
528
ApplicationProperties_t *appProperties = (ApplicationProperties_t *)(appStart->signature);
529
uint32_t appVersion = appProperties->app.version;
530
uint32_t emptySlots = bootload_remainingApplicationUpgrades();
531
uint32_t highestVersionSeen = getHighestApplicationVersionSeen();
532
uint32_t *appVersionStoragePtr = bootload_getApplicationVersionStoragePtr(SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY);
534
if (!bootload_checkApplicationPropertiesMagic(appProperties)) {
537
if (!bootload_checkApplicationPropertiesVersion(appProperties)) {
541
if (checkMaxVersionMagic()) {
542
// The highest allowed version is seen, which is the maximum version allowed
543
// so we do not need to remember any new application versions.
546
if (*appVersionStoragePtr != SL_GBL_UINT32_MAX_NUMBER) {
549
if (highestVersionSeen == appVersion) {
550
// Do not need to store a new version.
554
if (appVersion == SL_GBL_UINT32_MAX_NUMBER) {
555
appVersion = SL_GBL_APPLICATION_VERSION_MAX_MAGIC;
556
// Return true eventhough the flash pages are locked to avoid bricking devices.
557
(void)flash_writeBuffer_dma((uint32_t)appVersionStoragePtr, &appVersion, 4UL, SL_GBL_MSC_LDMA_CHANNEL);
561
// The application that is about to boot has a higher version than the highest seen version.
562
// However, this version can’t be stored, so do not allow the application to boot to prevent
563
// downgrade later. This will “never” happen as the number of empty slots is checked before getting to this point.
564
// Unless the slots are already filled for some unexpected reason.
565
if (emptySlots == 0UL) {
569
appVersionStoragePtr = bootload_getApplicationVersionStoragePtr(SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY - emptySlots);
570
(void)flash_writeBuffer_dma((uint32_t)appVersionStoragePtr, &appVersion, 4UL, SL_GBL_MSC_LDMA_CHANNEL);
578
bool bootload_verifyApplicationVersion(uint32_t appVersion, bool checkRemainingAppUpgrades)
580
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
581
uint32_t highestVersionSeen = getHighestApplicationVersionSeen();
583
// Check for the minimum application version that should be allowed.
584
if (PARSER_APPLICATION_MINIMUM_VERSION_VALID > appVersion) {
587
if (highestVersionSeen > appVersion) {
591
// Application version is higher/equal than the saved application versions.
592
// Check if we have empty spaces left for storing new application versions.
593
if ((appVersion > highestVersionSeen) && checkRemainingAppUpgrades) {
594
// The new application version needs to be stored, check we have empty spaces left.
595
if (bootload_remainingApplicationUpgrades() == 0UL) {
603
(void)checkRemainingAppUpgrades;
608
uint32_t bootload_remainingApplicationUpgrades(void)
610
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
611
uint32_t *appVersionStoragePtr = bootload_getApplicationVersionStoragePtr(SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY);
612
if (checkMaxVersionMagic()) {
616
for (uint32_t i = 0UL; i < SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY; i++) {
617
appVersionStoragePtr = bootload_getApplicationVersionStoragePtr(i);
618
if (*appVersionStoragePtr == SL_GBL_UINT32_MAX_NUMBER) {
619
return (SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY - i);
629
void bootload_storeApplicationVersionResetMagic(void)
631
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
632
uint32_t *appVersionResetPtr = bootload_getApplicationVersionStoragePtr(bootload_getApplicationVersionStorageCapacity() + 1UL);
633
uint32_t appVersionResetMagic = SL_GBL_APPLICATION_VERSION_RESET_MAGIC;
634
(void)flash_writeBuffer_dma((uint32_t)appVersionResetPtr, &appVersionResetMagic, 4UL, SL_GBL_MSC_LDMA_CHANNEL);
640
void bootload_removeStoredApplicationVersions(void)
642
#if defined(BOOTLOADER_ROLLBACK_PROTECTION) && (BOOTLOADER_ROLLBACK_PROTECTION == 1)
643
uint32_t *appVersionResetPtr = bootload_getApplicationVersionStoragePtr(SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY + 1UL);
644
if ((bootload_remainingApplicationUpgrades() < SL_GBL_APPLICATION_VERSION_STORAGE_CAPACITY)
645
&& checkResetMagic()) {
646
// Not empty and reset requested.
647
uint32_t versionStorageAddr = ((uint32_t)appVersionResetPtr / FLASH_PAGE_SIZE) * FLASH_PAGE_SIZE;
648
(void)flash_erasePage(versionStorageAddr);
655
bool bootload_gotCertificate(void *appProp)
657
#if defined(BOOTLOADER_SUPPORT_CERTIFICATES) && (BOOTLOADER_SUPPORT_CERTIFICATES == 1)
658
if (appProp == NULL) {
662
ApplicationProperties_t *appProperties = (ApplicationProperties_t *)(appProp);
663
// Compatibility check of the application properties struct.
664
// The application properties struct with the major version 0
665
// does not contain the certificate struct.
666
if (((appProperties->structVersion & APPLICATION_PROPERTIES_VERSION_MAJOR_MASK)
667
>> APPLICATION_PROPERTIES_VERSION_MAJOR_SHIFT) < 1UL) {
671
if (((appProperties->structVersion & APPLICATION_PROPERTIES_VERSION_MINOR_MASK)
672
>> APPLICATION_PROPERTIES_VERSION_MINOR_SHIFT) < 1UL) {
676
if (appProperties->cert == NULL) {
687
bool bootload_verifyCertificate(void *cert)
689
#if defined(BOOTLOADER_SUPPORT_CERTIFICATES) && (BOOTLOADER_SUPPORT_CERTIFICATES == 1)
693
ApplicationCertificate_t *appCertificate = (ApplicationCertificate_t *)(cert);
695
volatile int32_t retVal = BOOTLOADER_ERROR_SECURITY_REJECTED;
696
Sha256Context_t shaState;
698
// Access word 13 to read sl_app_properties of the bootloader.
699
ApplicationProperties_t *blProperties =
700
(ApplicationProperties_t *)(*(uint32_t *)(BTL_MAIN_STAGE_BASE + 52UL));
701
if (!bootload_checkApplicationPropertiesMagic(blProperties)) {
704
#if !defined(MAIN_BOOTLOADER_TEST)
705
if ((uint32_t)blProperties > (BTL_APPLICATION_BASE - sizeof(ApplicationProperties_t))) {
706
// Make sure that this pointer is within the bootloader space.
711
// Application cert version need to be higher or equal than
712
// the running bootloader version.
713
if (blProperties->cert->version > appCertificate->version) {
716
// Check ECDSA signing.
717
btl_initSha256(&shaState);
718
btl_updateSha256(&shaState,
719
(const uint8_t*)appCertificate,
721
btl_finalizeSha256(&shaState);
723
// Use the public key stored in bootloader certificate
724
// to verify the certificate. The bootloader cerfiticate
725
// has been validated by SE.
726
retVal = btl_verifyEcdsaP256r1(shaState.sha,
727
&(appCertificate->signature[0]),
728
&(appCertificate->signature[32]),
729
&(blProperties->cert->key[0]),
730
&(blProperties->cert->key[32]));
731
if (retVal != BOOTLOADER_OK) {
742
bool bootload_verifyApplicationCertificate(void *appProp, void *gotCert)
744
#if defined(BOOTLOADER_SUPPORT_CERTIFICATES) && (BOOTLOADER_SUPPORT_CERTIFICATES == 1)
745
ApplicationProperties_t *appProperties = (ApplicationProperties_t *)(appProp);
746
bool *gotCertificate = (bool *)gotCert;
747
*gotCertificate = bootload_gotCertificate(appProperties);
748
if (*gotCertificate) {
750
if (!bootload_verifyCertificate(appProperties->cert)) {
751
// Cert found, but it contains an invalid signature.
755
#if defined(BOOTLOADER_REJECT_DIRECT_SIGNED_IMG) && (BOOTLOADER_REJECT_DIRECT_SIGNED_IMG == 1)
768
// --------------------------------
769
// Secure Element functions
771
bool bootload_commitBootloaderUpgrade(uint32_t upgradeAddress, uint32_t size)
773
// Check CRC32 checksum on the bootloader image.
774
uint32_t crc = btl_crc32Stream((void *)upgradeAddress, (size_t)size, BTL_CRC32_START);
775
if (crc != BTL_CRC32_END) {
776
// CRC32 check failed. Return early.
780
#if defined(SEMAILBOX_PRESENT)
781
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
782
CMU->CLKEN1_SET = CMU_CLKEN1_SEMAILBOXHOST;
785
// Init with != SE_RESPONSE_OK response.
786
SE_Response_t response = 0x12345678U;
788
// Verify upgrade image
789
SE_Command_t checkImage = SE_COMMAND_DEFAULT(SE_COMMAND_CHECK_HOST_IMAGE);
790
SE_addParameter(&checkImage, upgradeAddress);
791
SE_addParameter(&checkImage, size);
793
SE_executeCommand(&checkImage);
794
response = SE_readCommandResponse();
796
if (response != SE_RESPONSE_OK) {
801
#if !defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
802
// Set Reset Magic to signal that the application versions should be cleaned.
803
// Doing this to make sure that those application versions gets cleaned with a bootloader upgrade.
804
// (Those versions will not get cleaned if the bootloader image does not require the last bootloader page).
805
bootload_storeApplicationVersionResetMagic();
808
#if defined(SEMAILBOX_PRESENT)
809
// Set reset code for when we get back
810
reset_setResetReason(BOOTLOADER_RESET_REASON_BOOTLOAD);
812
// Apply upgrade image
813
SE_Command_t applyImage = SE_COMMAND_DEFAULT(SE_COMMAND_APPLY_HOST_IMAGE);
814
SE_addParameter(&applyImage, upgradeAddress);
815
SE_addParameter(&applyImage, size);
817
SE_executeCommand(&applyImage);
819
// Should never get here
820
response = SE_readCommandResponse();
822
#elif defined(CRYPTOACC_PRESENT)
823
// Set reset code for when we get back
824
reset_setResetReason(BOOTLOADER_RESET_REASON_BOOTLOAD);
826
// Apply upgrade image
827
SE_Command_t applyImage = SE_COMMAND_DEFAULT(SE_COMMAND_APPLY_HOST_IMAGE);
828
SE_addParameter(&applyImage, upgradeAddress);
829
SE_addParameter(&applyImage, size);
831
SE_executeCommand(&applyImage);
833
// Should never get here
836
(void) upgradeAddress;
838
// Reboot and apply upgrade
839
reset_resetWithReason(BOOTLOADER_RESET_REASON_UPGRADE);
841
// Should never get here
846
#if defined(_MSC_PAGELOCK0_MASK)
847
bool bootload_lockApplicationArea(uint32_t startAddress, uint32_t endAddress)
849
if (endAddress == 0U) {
850
// It is assumed that a valid start address of application is used.
851
BareBootTable_t *appStart = (BareBootTable_t *)startAddress;
852
ApplicationProperties_t *appProperties = (ApplicationProperties_t *)(appStart->signature);
853
bool retVal = getSignatureX(appProperties, &endAddress);
855
BTL_DEBUG_PRINTLN(“Wrong s type”);
860
if (startAddress > endAddress) {
864
uint32_t volatile * pageLockAddr;
865
const uint32_t pageSize = (uint32_t)FLASH_PAGE_SIZE;
866
uint32_t pageNo = ((startAddress - (startAddress % pageSize)) - FLASH_BASE) / pageSize;
867
uint32_t endPageNo = ((endAddress - (endAddress % pageSize) + pageSize) - FLASH_BASE) / pageSize;
869
#if defined(CMU_CLKEN1_MSC)
870
CMU->CLKEN1_SET = CMU_CLKEN1_MSC;
872
while (pageNo < endPageNo) {
873
pageLockAddr = (uint32_t volatile *)(&(MSC->PAGELOCK0_SET));
874
// Find the page lock register that includes current page number.
875
pageLockAddr = &pageLockAddr[pageNo / 32U]; // 32 pages per page lock word.
876
*pageLockAddr = (1UL << (pageNo % 32U));
879
#if defined(CRYPTOACC_PRESENT)
880
CMU->CLKEN1_CLR = CMU_CLKEN1_MSC;
886
#if defined(SEMAILBOX_PRESENT)
887
bool bootload_checkSeUpgradeVersion(uint32_t upgradeVersion)
889
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
890
CMU->CLKEN1_SET = CMU_CLKEN1_SEMAILBOXHOST;
893
// Init with != SE_RESPONSE_OK response.
894
SE_Response_t response = 0x12345678U;
895
uint32_t runningVersion = 0xFFFFFFFFU;
897
SE_Command_t getVersion = SE_COMMAND_DEFAULT(SE_COMMAND_STATUS_SE_VERSION);
898
SE_DataTransfer_t dataOut = SE_DATATRANSFER_DEFAULT(&runningVersion, 4UL);
899
SE_addDataOutput(&getVersion, &dataOut);
901
SE_executeCommand(&getVersion);
902
response = SE_readCommandResponse();
904
if (response != SE_RESPONSE_OK) {
905
// Failed to communicate with SE, can’t apply SE upgrade.
909
// Only allow upgrade if it is higher than the running version
910
if (runningVersion < upgradeVersion) {
917
bool bootload_commitSeUpgrade(uint32_t upgradeAddress)
919
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
920
CMU->CLKEN1_SET = CMU_CLKEN1_SEMAILBOXHOST;
923
// Init with != SE_RESPONSE_OK response.
924
SE_Response_t response = 0x12345678U;
926
// Verify upgrade image
927
SE_Command_t checkImage = SE_COMMAND_DEFAULT(SE_COMMAND_CHECK_SE_IMAGE);
928
SE_addParameter(&checkImage, upgradeAddress);
930
SE_executeCommand(&checkImage);
931
response = SE_readCommandResponse();
933
if (response != SE_RESPONSE_OK) {
937
// Set reset code for when we get back
938
reset_setResetReason(BOOTLOADER_RESET_REASON_BOOTLOAD);
940
// Apply upgrade image
941
SE_Command_t applyImage = SE_COMMAND_DEFAULT(SE_COMMAND_APPLY_SE_IMAGE);
942
SE_addParameter(&applyImage, upgradeAddress);
944
SE_executeCommand(&applyImage);
946
// Should never get here
947
response = SE_readCommandResponse();
951
#elif defined(CRYPTOACC_PRESENT)
952
bool bootload_checkSeUpgradeVersion(uint32_t upgradeVersion)
954
uint32_t runningVersion = 0xFFFFFFFFU;
955
if (SE_getVersion(&runningVersion) != SE_RESPONSE_OK) {
956
// Failed to communicate with SE, can’t find the SE version.
959
// Only allow upgrade if it is higher than the running version
960
if (runningVersion < upgradeVersion) {
966
bool bootload_commitSeUpgrade(uint32_t upgradeAddress)
968
// Set reset code for when we get back
969
reset_setResetReason(BOOTLOADER_RESET_REASON_BOOTLOAD);
971
// Apply upgrade image
972
SE_Command_t applyImage = SE_COMMAND_DEFAULT(SE_COMMAND_APPLY_SE_IMAGE);
973
SE_addParameter(&applyImage, upgradeAddress);
975
SE_executeCommand(&applyImage);
977
// Should never get here
980
#endif // defined(CRYPTOACC_PRESENT)