forked from wolfSSL/wolfBoot
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathupdate_flash_hwswap.c
More file actions
133 lines (125 loc) · 4.07 KB
/
update_flash_hwswap.c
File metadata and controls
133 lines (125 loc) · 4.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* update_flash_hwswap.c
*
* Implementation for hardware assisted updater
*
*
* Copyright (C) 2025 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include "loader.h"
#include "image.h"
#include "hal.h"
#include "hooks.h"
#include "spi_flash.h"
#include "wolfboot/wolfboot.h"
#ifdef SECURE_PKCS11
int WP11_Library_Init(void);
#endif
extern void hal_flash_dualbank_swap(void);
static inline void boot_panic(void)
{
while(1)
;
}
void RAMFUNCTION wolfBoot_start(void)
{
int active;
struct wolfBoot_image fw_image;
uint8_t p_state;
#ifndef ALLOW_DOWNGRADE
uint32_t boot_v = wolfBoot_current_firmware_version();
uint32_t update_v = wolfBoot_update_firmware_version();
uint32_t max_v = (boot_v > update_v) ? boot_v : update_v;
#endif
active = wolfBoot_dualboot_candidate();
if (active < 0) /* panic if no images available */
boot_panic();
for (;;) {
#ifndef ALLOW_DOWNGRADE
uint32_t active_v = (active == PART_UPDATE) ? update_v : boot_v;
if ((max_v > 0U) && (active_v < max_v)) {
wolfBoot_printf("Rollback to lower version not allowed\n");
boot_panic();
}
#endif
if ((wolfBoot_open_image(&fw_image, active) < 0)
#ifndef WOLFBOOT_SKIP_BOOT_VERIFY
|| (wolfBoot_verify_integrity(&fw_image) < 0)
|| (wolfBoot_verify_authenticity(&fw_image) < 0)
#endif
) {
/* panic if authentication fails and no backup */
if (!wolfBoot_fallback_is_possible())
boot_panic();
else {
/* Invalidate failing image and switch to the
* other partition
*/
wolfBoot_erase_partition(active);
active ^= 1;
}
} else
break; /* candidate successfully authenticated */
}
/* First time we boot this update, set to TESTING to await
* confirmation from the system
*/
if ((active == PART_BOOT) && (wolfBoot_get_partition_state(active, &p_state) == 0) &&
(p_state == IMG_STATE_UPDATING))
{
hal_flash_unlock();
wolfBoot_set_partition_state(active, IMG_STATE_TESTING);
hal_flash_lock();
}
/* Booting from update is possible via HW-assisted swap */
if (active == PART_UPDATE) {
hal_flash_dualbank_swap();
/* On some platform, e.g. STM32L5, hal_flash_dualbank_swap
* never returns. A reboot is triggered instead, so the code
* below is only executed if we are staging the firmware.
*/
active = PART_BOOT;
if ((wolfBoot_get_partition_state(active, &p_state) == 0) &&
(p_state == IMG_STATE_UPDATING))
{
hal_flash_unlock();
wolfBoot_set_partition_state(active, IMG_STATE_TESTING);
hal_flash_lock();
}
}
#ifdef SECURE_PKCS11
WP11_Library_Init();
#endif
#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT
(void)hal_hsm_disconnect();
#elif defined(WOLFBOOT_ENABLE_WOLFHSM_SERVER)
(void)hal_hsm_server_cleanup();
#endif
#ifndef TZEN
if (hal_flash_protect(WOLFBOOT_ORIGIN, BOOTLOADER_PARTITION_SIZE) < 0)
boot_panic();
#endif
hal_prepare_boot();
#ifdef WOLFBOOT_HOOK_BOOT
wolfBoot_hook_boot(&fw_image);
#endif
#ifndef WOLFBOOT_SKIP_BOOT_VERIFY
PART_SANITY_CHECK(&fw_image);
#endif
do_boot((void *)(WOLFBOOT_PARTITION_BOOT_ADDRESS + IMAGE_HEADER_SIZE));
}