/src/wolfBoot/include/image.h
Line | Count | Source |
1 | | /* image.h |
2 | | * |
3 | | * Functions to help with wolfBoot image header |
4 | | * |
5 | | * |
6 | | * Copyright (C) 2026 wolfSSL Inc. |
7 | | * |
8 | | * This file is part of wolfBoot. |
9 | | * |
10 | | * wolfBoot is free software; you can redistribute it and/or modify |
11 | | * it under the terms of the GNU General Public License as published by |
12 | | * the Free Software Foundation; either version 3 of the License, or |
13 | | * (at your option) any later version. |
14 | | * |
15 | | * wolfBoot is distributed in the hope that it will be useful, |
16 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | | * GNU General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU General Public License |
21 | | * along with this program; if not, write to the Free Software |
22 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
23 | | */ |
24 | | |
25 | | #ifndef IMAGE_H |
26 | | #define IMAGE_H |
27 | | |
28 | | #ifdef __cplusplus |
29 | | extern "C" { |
30 | | #endif |
31 | | |
32 | | #include <stdint.h> |
33 | | |
34 | | #include "target.h" |
35 | | #include "wolfboot/wolfboot.h" |
36 | | |
37 | | #ifdef EXT_FLASH |
38 | | #include "hal.h" |
39 | | #endif |
40 | | |
41 | | #if defined(EXT_ENCRYPTED) && (defined(__WOLFBOOT) || defined(UNIT_TEST)) |
42 | | #include "encrypt.h" |
43 | | #endif |
44 | | |
45 | | #ifndef WOLFBOOT_FLAGS_INVERT |
46 | | #define SECT_FLAG_NEW 0x0F |
47 | | #define SECT_FLAG_SWAPPING 0x07 |
48 | | #define SECT_FLAG_BACKUP 0x03 |
49 | | #define SECT_FLAG_UPDATED 0x00 |
50 | | #else |
51 | | #define SECT_FLAG_NEW 0x00 |
52 | | #define SECT_FLAG_SWAPPING 0x08 |
53 | | #define SECT_FLAG_BACKUP 0x0c |
54 | | #define SECT_FLAG_UPDATED 0x0f |
55 | | #endif |
56 | | |
57 | | #ifdef WOLFBOOT_SIGN_ED25519 |
58 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_ed25519 |
59 | | #endif |
60 | | #ifdef WOLFBOOT_SIGN_ED448 |
61 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_ed448 |
62 | | #endif |
63 | | #if defined (WOLFBOOT_SIGN_RSA2048) || \ |
64 | | defined (WOLFBOOT_SIGN_RSA3072) || \ |
65 | | defined (WOLFBOOT_SIGN_RSA4096) || \ |
66 | | defined (WOLFBOOT_SIGN_RSA2048ENC) || \ |
67 | | defined (WOLFBOOT_SIGN_RSA3072ENC) || \ |
68 | | defined (WOLFBOOT_SIGN_RSA4096ENC) |
69 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_rsa |
70 | | #endif |
71 | | #if defined (WOLFBOOT_SIGN_RSAPSS2048) || \ |
72 | | defined (WOLFBOOT_SIGN_RSAPSS3072) || \ |
73 | | defined (WOLFBOOT_SIGN_RSAPSS4096) |
74 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_rsa_pss |
75 | | #endif |
76 | | #if defined (WOLFBOOT_SIGN_ECC256) || \ |
77 | | defined (WOLFBOOT_SIGN_ECC384) || \ |
78 | | defined (WOLFBOOT_SIGN_ECC521) |
79 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_ecc |
80 | | #endif |
81 | | #if defined(WOLFBOOT_SIGN_LMS) |
82 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_lms |
83 | | #endif |
84 | | #if defined(WOLFBOOT_SIGN_XMSS ) |
85 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_xmss |
86 | | #endif |
87 | | #ifdef WOLFBOOT_SIGN_ML_DSA |
88 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_ml_dsa |
89 | | #endif |
90 | | |
91 | | #ifdef WOLFBOOT_SIGN_SECONDARY_ED25519 |
92 | | #define wolfBoot_verify_signature_secondary wolfBoot_verify_signature_ed25519 |
93 | | #endif |
94 | | #ifdef WOLFBOOT_SIGN_SECONDARY_ED448 |
95 | | #define wolfBoot_verify_signature_secondary wolfBoot_verify_signature_ed448 |
96 | | #endif |
97 | | #if defined (WOLFBOOT_SIGN_SECONDARY_RSA2048) || \ |
98 | | defined (WOLFBOOT_SIGN_SECONDARY_RSA3072) || \ |
99 | | defined (WOLFBOOT_SIGN_SECONDARY_RSA4096) || \ |
100 | | defined (WOLFBOOT_SIGN_SECONDARY_RSA2048ENC) || \ |
101 | | defined (WOLFBOOT_SIGN_SECONDARY_RSA3072ENC) || \ |
102 | | defined (WOLFBOOT_SIGN_SECONDARY_RSA4096ENC) |
103 | | #define wolfBoot_verify_signature_secondary wolfBoot_verify_signature_rsa |
104 | | #endif |
105 | | #if defined (WOLFBOOT_SIGN_SECONDARY_RSAPSS2048) || \ |
106 | | defined (WOLFBOOT_SIGN_SECONDARY_RSAPSS3072) || \ |
107 | | defined (WOLFBOOT_SIGN_SECONDARY_RSAPSS4096) |
108 | | #define wolfBoot_verify_signature_secondary wolfBoot_verify_signature_rsa_pss |
109 | | #endif |
110 | | #if defined (WOLFBOOT_SIGN_SECONDARY_ECC256) || \ |
111 | | defined (WOLFBOOT_SIGN_SECONDARY_ECC384) || \ |
112 | | defined (WOLFBOOT_SIGN_SECONDARY_ECC521) |
113 | | #define wolfBoot_verify_signature_secondary wolfBoot_verify_signature_ecc |
114 | | #endif |
115 | | #ifdef WOLFBOOT_SIGN_SECONDARY_LMS |
116 | | #define wolfBoot_verify_signature_secondary wolfBoot_verify_signature_lms |
117 | | #endif |
118 | | #ifdef WOLFBOOT_SIGN_SECONDARY_XMSS |
119 | | #define wolfBoot_verify_signature_secondary wolfBoot_verify_signature_xmss |
120 | | #endif |
121 | | #ifdef WOLFBOOT_SIGN_SECONDARY_ML_DSA |
122 | | #define wolfBoot_verify_signature_secondary wolfBoot_verify_signature_ml_dsa |
123 | | #endif |
124 | | |
125 | | /* Thin wrappers: dispatch RSA / RSA-PSS to the unified verify function */ |
126 | | #define wolfBoot_verify_signature_rsa(ks, img, sig) \ |
127 | | wolfBoot_verify_signature_rsa_common(ks, img, sig, 0) |
128 | | #define wolfBoot_verify_signature_rsa_pss(ks, img, sig) \ |
129 | | wolfBoot_verify_signature_rsa_common(ks, img, sig, 1) |
130 | | |
131 | | #if defined(WOLFBOOT_TPM) && defined (WOLFBOOT_TPM_VERIFY) |
132 | | #undef wolfBoot_verify_signature_primary |
133 | | #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_tpm |
134 | | #endif |
135 | | |
136 | | /* Validate sector size is larger than image header size */ |
137 | | #if defined(WOLFBOOT_SECTOR_SIZE) && defined(IMAGE_HEADER_SIZE) && \ |
138 | | (WOLFBOOT_SECTOR_SIZE < IMAGE_HEADER_SIZE) |
139 | | #error WOLFBOOT_SECTOR_SIZE must be larger than IMAGE_HEADER_SIZE |
140 | | #endif |
141 | | |
142 | | |
143 | | #if (defined(WOLFBOOT_ARMORED) && defined(__WOLFBOOT)) |
144 | | #if !defined(ARCH_ARM) || (!defined(__GNUC__) && \ |
145 | | !(defined(__ICCARM__) && defined(__IAR_SYSTEMS_ICC__))) |
146 | | # error WOLFBOOT_ARMORED only available for ARM with IAR or gcc compilers |
147 | | #endif |
148 | | |
149 | | #if defined(__GNUC__) |
150 | | #define likely(x) __builtin_expect((x),1) |
151 | | #define unlikely(x) __builtin_expect((x),0) |
152 | | #else |
153 | | #define likely(x) (x) |
154 | | #define unlikely(x) (x) |
155 | | #endif |
156 | | |
157 | | struct wolfBoot_image { |
158 | | uint8_t *hdr; |
159 | | #ifdef EXT_FLASH |
160 | | uint8_t *hdr_cache; |
161 | | #endif |
162 | | uint8_t *trailer; |
163 | | uint8_t *sha_hash; |
164 | | uint8_t *fw_base; |
165 | | uint32_t fw_size; |
166 | | uint32_t part; |
167 | | uint32_t hdr_ok; |
168 | | uint32_t canary_FEED4567; |
169 | | uint32_t signature_ok; |
170 | | uint32_t canary_FEED6789; |
171 | | uint32_t not_signature_ok; |
172 | | uint32_t canary_FEED89AB; |
173 | | uint32_t sha_ok; |
174 | | uint32_t not_ext; /* image is no longer external */ |
175 | | }; |
176 | | |
177 | | |
178 | | /** |
179 | | * This function sets the flag that indicates the signature is valid for the |
180 | | * wolfBoot_image. |
181 | | * |
182 | | * With ARMORED setup, the flag is redundant, and the information is wrapped in |
183 | | * between canary variables, to mitigate attacks based on memory corruptions. |
184 | | */ |
185 | | static void NOINLINEFUNCTION wolfBoot_image_confirm_signature_ok( |
186 | | struct wolfBoot_image *img) |
187 | | { |
188 | | img->canary_FEED4567 = 0xFEED4567UL; |
189 | | img->signature_ok = 1UL; |
190 | | img->canary_FEED6789 = 0xFEED6789UL; |
191 | | img->not_signature_ok = ~(1UL); |
192 | | img->canary_FEED89AB = 0xFEED89ABUL; |
193 | | } |
194 | | |
195 | | static void NOINLINEFUNCTION wolfBoot_image_clear_signature_ok( |
196 | | struct wolfBoot_image *img) |
197 | | { |
198 | | img->canary_FEED4567 = 0xFEED4567UL; |
199 | | img->signature_ok = 0UL; |
200 | | img->canary_FEED6789 = 0xFEED6789UL; |
201 | | img->not_signature_ok = 1UL; |
202 | | img->canary_FEED89AB = 0xFEED89ABUL; |
203 | | } |
204 | | |
205 | | /** |
206 | | * Final sanity check, performed just before do_boot, or before starting an |
207 | | * update that has been verified. |
208 | | * |
209 | | * This procedure detects if any of the previous checks has been skipped. |
210 | | * If any of the required flags does not match the expected value, wolfBoot |
211 | | * panics. |
212 | | */ |
213 | | #define PART_SANITY_CHECK(p) \ |
214 | | /* Redundant set of r2=0 */ \ |
215 | | asm volatile("mov r2, #0":::"r2"); \ |
216 | | asm volatile("mov r2, #0":::"r2"); \ |
217 | | asm volatile("mov r2, #0":::"r2"); \ |
218 | | asm volatile("mov r2, #0":::"r2"); \ |
219 | | asm volatile("mov r2, #0":::"r2"); \ |
220 | | /* Loading hdr_ok flag, verifying */ \ |
221 | | asm volatile("mov r2, %0" ::"r"((p)->hdr_ok):"r2"); \ |
222 | | asm volatile("cmp r2, #1":::"cc"); \ |
223 | | asm volatile("cmp r2, #1":::"cc"); \ |
224 | | asm volatile("cmp r2, #1":::"cc"); \ |
225 | | asm volatile("bne ."); \ |
226 | | asm volatile("cmp r2, #1":::"cc"); \ |
227 | | asm volatile("cmp r2, #1":::"cc"); \ |
228 | | asm volatile("cmp r2, #1":::"cc"); \ |
229 | | asm volatile("bne .-4"); \ |
230 | | asm volatile("cmp r2, #1":::"cc"); \ |
231 | | asm volatile("cmp r2, #1":::"cc"); \ |
232 | | asm volatile("cmp r2, #1":::"cc"); \ |
233 | | asm volatile("bne .-8"); \ |
234 | | asm volatile("cmp r2, #1":::"cc"); \ |
235 | | asm volatile("cmp r2, #1":::"cc"); \ |
236 | | asm volatile("cmp r2, #1":::"cc"); \ |
237 | | asm volatile("bne .-12"); \ |
238 | | /* Redundant set of r2=0 */ \ |
239 | | asm volatile("mov r2, #0":::"r2"); \ |
240 | | asm volatile("mov r2, #0":::"r2"); \ |
241 | | asm volatile("mov r2, #0":::"r2"); \ |
242 | | asm volatile("mov r2, #0":::"r2"); \ |
243 | | asm volatile("mov r2, #0":::"r2"); \ |
244 | | /* Loading hdr_ok flag, verifying */ \ |
245 | | asm volatile("mov r2, %0" ::"r"((p)->sha_ok):"r2"); \ |
246 | | asm volatile("cmp r2, #1":::"cc"); \ |
247 | | asm volatile("cmp r2, #1":::"cc"); \ |
248 | | asm volatile("cmp r2, #1":::"cc"); \ |
249 | | asm volatile("bne ."); \ |
250 | | asm volatile("cmp r2, #1":::"cc"); \ |
251 | | asm volatile("cmp r2, #1":::"cc"); \ |
252 | | asm volatile("cmp r2, #1":::"cc"); \ |
253 | | asm volatile("bne .-4"); \ |
254 | | asm volatile("cmp r2, #1":::"cc"); \ |
255 | | asm volatile("cmp r2, #1":::"cc"); \ |
256 | | asm volatile("cmp r2, #1":::"cc"); \ |
257 | | asm volatile("bne .-8"); \ |
258 | | asm volatile("cmp r2, #1":::"cc"); \ |
259 | | asm volatile("cmp r2, #1":::"cc"); \ |
260 | | asm volatile("cmp r2, #1":::"cc"); \ |
261 | | asm volatile("bne .-12"); \ |
262 | | /* Redundant set of r2=0 */ \ |
263 | | asm volatile("mov r2, #0":::"r2"); \ |
264 | | asm volatile("mov r2, #0":::"r2"); \ |
265 | | asm volatile("mov r2, #0":::"r2"); \ |
266 | | asm volatile("mov r2, #0":::"r2"); \ |
267 | | asm volatile("mov r2, #0":::"r2"); \ |
268 | | /* Loading signature_ok flag, verifying */ \ |
269 | | asm volatile("mov r2, %0" ::"r"((p)->signature_ok):"r2"); \ |
270 | | asm volatile("cmp r2, #1":::"cc"); \ |
271 | | asm volatile("cmp r2, #1":::"cc"); \ |
272 | | asm volatile("cmp r2, #1":::"cc"); \ |
273 | | asm volatile("bne ."); \ |
274 | | asm volatile("cmp r2, #1":::"cc"); \ |
275 | | asm volatile("cmp r2, #1":::"cc"); \ |
276 | | asm volatile("cmp r2, #1":::"cc"); \ |
277 | | asm volatile("bne .-4"); \ |
278 | | asm volatile("cmp r2, #1":::"cc"); \ |
279 | | asm volatile("cmp r2, #1":::"cc"); \ |
280 | | asm volatile("cmp r2, #1":::"cc"); \ |
281 | | asm volatile("bne .-8"); \ |
282 | | asm volatile("cmp r2, #1":::"cc"); \ |
283 | | asm volatile("cmp r2, #1":::"cc"); \ |
284 | | asm volatile("cmp r2, #1":::"cc"); \ |
285 | | asm volatile("bne .-12"); \ |
286 | | /* Redundant set of r2=0 */ \ |
287 | | asm volatile("mov r2, #0"); \ |
288 | | asm volatile("mov r2, #0"); \ |
289 | | asm volatile("mov r2, #0"); \ |
290 | | asm volatile("mov r2, #0"); \ |
291 | | asm volatile("mov r2, #0"); \ |
292 | | /* Loading ~(signature_ok) flag, verifying */ \ |
293 | | asm volatile("mov r2, %0" ::"r"((p)->not_signature_ok):"r2"); \ |
294 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
295 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
296 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
297 | | asm volatile("bne ."); \ |
298 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
299 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
300 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
301 | | asm volatile("bne .-4"); \ |
302 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
303 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
304 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
305 | | asm volatile("bne .-8"); \ |
306 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
307 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
308 | | asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ |
309 | | asm volatile("bne .-12"); \ |
310 | | /* Redundant set of r2=0 */ \ |
311 | | asm volatile("mov r2, #0":::"r2"); \ |
312 | | asm volatile("mov r2, #0":::"r2"); \ |
313 | | asm volatile("mov r2, #0":::"r2"); \ |
314 | | asm volatile("mov r2, #0":::"r2"); \ |
315 | | asm volatile("mov r2, #0":::"r2"); \ |
316 | | /* Loading canary value, verifying */ \ |
317 | | asm volatile("mov r2, %0" ::"r"((p)->canary_FEED6789):"r2"); \ |
318 | | asm volatile("mov r0, %0" ::"r"(0xFEED6789):"r0"); \ |
319 | | asm volatile("cmp r2, r0":::"cc"); \ |
320 | | asm volatile("cmp r2, r0":::"cc"); \ |
321 | | asm volatile("cmp r2, r0":::"cc"); \ |
322 | | asm volatile("bne ."); \ |
323 | | asm volatile("cmp r2, r0":::"cc"); \ |
324 | | asm volatile("cmp r2, r0":::"cc"); \ |
325 | | asm volatile("cmp r2, r0":::"cc"); \ |
326 | | asm volatile("bne .-4"); \ |
327 | | asm volatile("cmp r2, r0":::"cc"); \ |
328 | | asm volatile("cmp r2, r0":::"cc"); \ |
329 | | asm volatile("cmp r2, r0":::"cc"); \ |
330 | | asm volatile("bne .-8"); \ |
331 | | asm volatile("cmp r2, r0":::"cc"); \ |
332 | | asm volatile("cmp r2, r0":::"cc"); \ |
333 | | asm volatile("cmp r2, r0":::"cc"); \ |
334 | | asm volatile("bne .-12"); \ |
335 | | /* Redundant set of r2=0 */ \ |
336 | | asm volatile("mov r2, #0":::"r2"); \ |
337 | | asm volatile("mov r2, #0":::"r2"); \ |
338 | | asm volatile("mov r2, #0":::"r2"); \ |
339 | | asm volatile("mov r2, #0":::"r2"); \ |
340 | | asm volatile("mov r2, #0":::"r2"); \ |
341 | | /* Loading canary value, verifying */ \ |
342 | | asm volatile("mov r2, %0" ::"r"((p)->canary_FEED4567):"r2"); \ |
343 | | asm volatile("mov r0, %0" ::"r"(0xFEED4567):"r0"); \ |
344 | | asm volatile("cmp r2, r0":::"cc"); \ |
345 | | asm volatile("cmp r2, r0":::"cc"); \ |
346 | | asm volatile("cmp r2, r0":::"cc"); \ |
347 | | asm volatile("bne ."); \ |
348 | | asm volatile("cmp r2, r0":::"cc"); \ |
349 | | asm volatile("cmp r2, r0":::"cc"); \ |
350 | | asm volatile("cmp r2, r0":::"cc"); \ |
351 | | asm volatile("bne .-4"); \ |
352 | | asm volatile("cmp r2, r0":::"cc"); \ |
353 | | asm volatile("cmp r2, r0":::"cc"); \ |
354 | | asm volatile("cmp r2, r0":::"cc"); \ |
355 | | asm volatile("bne .-8"); \ |
356 | | asm volatile("cmp r2, r0":::"cc"); \ |
357 | | asm volatile("cmp r2, r0":::"cc"); \ |
358 | | asm volatile("cmp r2, r0":::"cc"); \ |
359 | | asm volatile("bne .-12"); \ |
360 | | /* Redundant set of r2=0 */ \ |
361 | | asm volatile("mov r2, #0":::"r2"); \ |
362 | | asm volatile("mov r2, #0":::"r2"); \ |
363 | | asm volatile("mov r2, #0":::"r2"); \ |
364 | | asm volatile("mov r2, #0":::"r2"); \ |
365 | | asm volatile("mov r2, #0":::"r2"); \ |
366 | | /* Loading canary value, verifying */ \ |
367 | | asm volatile("mov r2, %0" ::"r"((p)->canary_FEED89AB):"r2"); \ |
368 | | asm volatile("mov r0, %0" ::"r"(0xFEED89AB):"r0"); \ |
369 | | asm volatile("cmp r2, r0":::"cc"); \ |
370 | | asm volatile("cmp r2, r0":::"cc"); \ |
371 | | asm volatile("cmp r2, r0":::"cc"); \ |
372 | | asm volatile("bne ."); \ |
373 | | asm volatile("cmp r2, r0":::"cc"); \ |
374 | | asm volatile("cmp r2, r0":::"cc"); \ |
375 | | asm volatile("cmp r2, r0":::"cc"); \ |
376 | | asm volatile("bne .-4"); \ |
377 | | asm volatile("cmp r2, r0":::"cc"); \ |
378 | | asm volatile("cmp r2, r0":::"cc"); \ |
379 | | asm volatile("cmp r2, r0":::"cc"); \ |
380 | | asm volatile("bne .-8"); \ |
381 | | asm volatile("cmp r2, r0":::"cc"); \ |
382 | | asm volatile("cmp r2, r0":::"cc"); \ |
383 | | asm volatile("cmp r2, r0":::"cc"); \ |
384 | | asm volatile("bne .-12") \ |
385 | | |
386 | | /** |
387 | | * First part of RSA verification. Ensure that the function is called by |
388 | | * double checking its return value contains a valid |
389 | | * len (>= WOLFBOOT_SHA_DIGEST_SIZE). |
390 | | * |
391 | | * Uses GAS local numeric labels (1f/1:) so the macro can be safely expanded |
392 | | * multiple times in the same function (e.g. RSA PKCS#1.5 + RSA-PSS paths). |
393 | | */ |
394 | | #define RSA_VERIFY_FN(ret,fn,...) \ |
395 | | { \ |
396 | | /* Redundant set of r0=0 */ \ |
397 | | asm volatile("mov r0, #0":::"r0"); \ |
398 | | asm volatile("mov r0, #0":::"r0"); \ |
399 | | asm volatile("mov r0, #0":::"r0"); \ |
400 | | /* Call the function */ \ |
401 | | int tmp_ret = fn(__VA_ARGS__); \ |
402 | | ret = -1; \ |
403 | | /* Redundant set of r2=SHA_DIGEST_SIZE */ \ |
404 | | asm volatile("mov r2, %0" ::"r"(WOLFBOOT_SHA_DIGEST_SIZE):"r2"); \ |
405 | | asm volatile("mov r2, %0" ::"r"(WOLFBOOT_SHA_DIGEST_SIZE):"r2"); \ |
406 | | asm volatile("mov r2, %0" ::"r"(WOLFBOOT_SHA_DIGEST_SIZE):"r2"); \ |
407 | | /* Redundant check for fn() return value >= r2 */ \ |
408 | | asm volatile("cmp r0, r2":::"cc"); \ |
409 | | asm volatile("cmp r0, r2":::"cc"); \ |
410 | | asm volatile("cmp r0, r2":::"cc"); \ |
411 | | asm volatile("blt 1f"); \ |
412 | | asm volatile("cmp r0, r2":::"cc"); \ |
413 | | asm volatile("cmp r0, r2":::"cc"); \ |
414 | | asm volatile("cmp r0, r2":::"cc"); \ |
415 | | asm volatile("blt 1f"); \ |
416 | | asm volatile("cmp r0, r2":::"cc"); \ |
417 | | asm volatile("cmp r0, r2":::"cc"); \ |
418 | | asm volatile("cmp r0, r2":::"cc"); \ |
419 | | asm volatile("blt 1f"); \ |
420 | | asm volatile("cmp r0, r2":::"cc"); \ |
421 | | asm volatile("cmp r0, r2":::"cc"); \ |
422 | | asm volatile("cmp r0, r2":::"cc"); \ |
423 | | asm volatile("blt 1f"); \ |
424 | | /* Return value is set here in case of success */ \ |
425 | | ret = tmp_ret; \ |
426 | | asm volatile("1:"); \ |
427 | | asm volatile("nop"); \ |
428 | | } |
429 | | |
430 | | /** |
431 | | * Second part of RSA verification. |
432 | | * |
433 | | * Compare the digest twice, then confirm via |
434 | | * wolfBoot_image_confirm_signature_ok(); |
435 | | * |
436 | | * Uses GAS local numeric labels (2f/2:) for safe multi-expansion. |
437 | | */ |
438 | | #define RSA_VERIFY_HASH(img,digest) \ |
439 | | { \ |
440 | | volatile int compare_res; \ |
441 | | if (!img || !digest) \ |
442 | | asm volatile("b 2f"); \ |
443 | | /* Redundant set of r0=50*/ \ |
444 | | asm volatile("mov r0, #50":::"r0"); \ |
445 | | asm volatile("mov r0, #50":::"r0"); \ |
446 | | asm volatile("mov r0, #50":::"r0"); \ |
447 | | compare_res = image_CT_compare(digest, img->sha_hash, \ |
448 | | WOLFBOOT_SHA_DIGEST_SIZE); \ |
449 | | /* Redundant checks that ensure the function actually returned 0 */ \ |
450 | | asm volatile("cmp r0, #0":::"cc"); \ |
451 | | asm volatile("cmp r0, #0":::"cc"); \ |
452 | | asm volatile("cmp r0, #0":::"cc"); \ |
453 | | asm volatile("bne 2f":::"cc"); \ |
454 | | asm volatile("cmp r0, #0"); \ |
455 | | asm volatile("cmp r0, #0"); \ |
456 | | asm volatile("cmp r0, #0"); \ |
457 | | asm volatile("bne 2f":::"cc"); \ |
458 | | asm volatile("cmp r0, #0":::"cc"); \ |
459 | | asm volatile("cmp r0, #0":::"cc"); \ |
460 | | asm volatile("cmp r0, #0":::"cc"); \ |
461 | | asm volatile("bne 2f"); \ |
462 | | asm volatile("cmp r0, #0":::"cc"); \ |
463 | | asm volatile("cmp r0, #0":::"cc"); \ |
464 | | asm volatile("cmp r0, #0":::"cc"); \ |
465 | | asm volatile("bne 2f"); \ |
466 | | /* Repeat comparison call */ \ |
467 | | compare_res = image_CT_compare(digest, img->sha_hash, \ |
468 | | WOLFBOOT_SHA_DIGEST_SIZE); \ |
469 | | compare_res; \ |
470 | | /* Redundant checks that ensure the function actually returned 0 */ \ |
471 | | asm volatile("cmp r0, #0":::"cc"); \ |
472 | | asm volatile("cmp r0, #0":::"cc"); \ |
473 | | asm volatile("cmp r0, #0":::"cc"); \ |
474 | | asm volatile("bne 2f"); \ |
475 | | asm volatile("cmp r0, #0":::"cc"); \ |
476 | | asm volatile("cmp r0, #0":::"cc"); \ |
477 | | asm volatile("cmp r0, #0":::"cc"); \ |
478 | | asm volatile("bne 2f"); \ |
479 | | asm volatile("cmp r0, #0":::"cc"); \ |
480 | | asm volatile("cmp r0, #0":::"cc"); \ |
481 | | asm volatile("cmp r0, #0":::"cc"); \ |
482 | | asm volatile("bne 2f"); \ |
483 | | asm volatile("cmp r0, #0":::"cc"); \ |
484 | | asm volatile("cmp r0, #0":::"cc"); \ |
485 | | asm volatile("cmp r0, #0":::"cc"); \ |
486 | | asm volatile("bne 2f"); \ |
487 | | /* Confirm that the signature is OK */ \ |
488 | | wolfBoot_image_confirm_signature_ok(img); \ |
489 | | asm volatile("2:"); \ |
490 | | asm volatile("nop"); \ |
491 | | } |
492 | | |
493 | | /** |
494 | | * Second part of RSA-PSS verification. |
495 | | * |
496 | | * Call wc_RsaPSS_CheckPadding twice, then confirm via |
497 | | * wolfBoot_image_confirm_signature_ok(); |
498 | | * |
499 | | * Uses GAS local numeric labels (3f/3:) for safe multi-expansion. |
500 | | */ |
501 | | #define RSA_PSS_VERIFY_HASH(img, pss_data, pss_data_sz, hash_type) \ |
502 | | { \ |
503 | | volatile int pss_res; \ |
504 | | if (!img || !pss_data) \ |
505 | | asm volatile("b 3f"); \ |
506 | | /* Redundant set of r0=50*/ \ |
507 | | asm volatile("mov r0, #50":::"r0"); \ |
508 | | asm volatile("mov r0, #50":::"r0"); \ |
509 | | asm volatile("mov r0, #50":::"r0"); \ |
510 | | pss_res = wc_RsaPSS_CheckPadding(img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, \ |
511 | | pss_data, pss_data_sz, hash_type); \ |
512 | | /* Redundant checks that ensure the function actually returned 0 */ \ |
513 | | asm volatile("cmp r0, #0":::"cc"); \ |
514 | | asm volatile("cmp r0, #0":::"cc"); \ |
515 | | asm volatile("cmp r0, #0":::"cc"); \ |
516 | | asm volatile("bne 3f":::"cc"); \ |
517 | | asm volatile("cmp r0, #0"); \ |
518 | | asm volatile("cmp r0, #0"); \ |
519 | | asm volatile("cmp r0, #0"); \ |
520 | | asm volatile("bne 3f":::"cc"); \ |
521 | | asm volatile("cmp r0, #0":::"cc"); \ |
522 | | asm volatile("cmp r0, #0":::"cc"); \ |
523 | | asm volatile("cmp r0, #0":::"cc"); \ |
524 | | asm volatile("bne 3f"); \ |
525 | | asm volatile("cmp r0, #0":::"cc"); \ |
526 | | asm volatile("cmp r0, #0":::"cc"); \ |
527 | | asm volatile("cmp r0, #0":::"cc"); \ |
528 | | asm volatile("bne 3f"); \ |
529 | | /* Repeat wc_RsaPSS_CheckPadding call */ \ |
530 | | pss_res = wc_RsaPSS_CheckPadding(img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, \ |
531 | | pss_data, pss_data_sz, hash_type); \ |
532 | | pss_res; \ |
533 | | /* Redundant checks that ensure the function actually returned 0 */ \ |
534 | | asm volatile("cmp r0, #0":::"cc"); \ |
535 | | asm volatile("cmp r0, #0":::"cc"); \ |
536 | | asm volatile("cmp r0, #0":::"cc"); \ |
537 | | asm volatile("bne 3f"); \ |
538 | | asm volatile("cmp r0, #0":::"cc"); \ |
539 | | asm volatile("cmp r0, #0":::"cc"); \ |
540 | | asm volatile("cmp r0, #0":::"cc"); \ |
541 | | asm volatile("bne 3f"); \ |
542 | | asm volatile("cmp r0, #0":::"cc"); \ |
543 | | asm volatile("cmp r0, #0":::"cc"); \ |
544 | | asm volatile("cmp r0, #0":::"cc"); \ |
545 | | asm volatile("bne 3f"); \ |
546 | | asm volatile("cmp r0, #0":::"cc"); \ |
547 | | asm volatile("cmp r0, #0":::"cc"); \ |
548 | | asm volatile("cmp r0, #0":::"cc"); \ |
549 | | asm volatile("bne 3f"); \ |
550 | | /* Confirm that the signature is OK */ \ |
551 | | wolfBoot_image_confirm_signature_ok(img); \ |
552 | | asm volatile("3:"); \ |
553 | | asm volatile("nop"); \ |
554 | | } |
555 | | |
556 | | /** |
557 | | * ECC / Ed / PQ signature verification. |
558 | | * Those verify functions set an additional value 'p_res' |
559 | | * which is passed as a pointer. |
560 | | * |
561 | | * Ensure that the verification function has been called, and then |
562 | | * set the return value accordingly. |
563 | | * |
564 | | * Double check by reading the value in p_res from memory a few times. |
565 | | * |
566 | | * Uses GAS local numeric labels (4f/4:) for safe multi-expansion. |
567 | | */ |
568 | | #if defined(__GNUC__) |
569 | | |
570 | | #define VERIFY_FN(img,p_res,fn,...) \ |
571 | | /* Redundant set of r0=50*/ \ |
572 | | asm volatile("mov r0, #50":::"r0"); \ |
573 | | asm volatile("mov r0, #50":::"r0"); \ |
574 | | asm volatile("mov r0, #50":::"r0"); \ |
575 | | /* Call the verify function */ \ |
576 | | fn(__VA_ARGS__); \ |
577 | | /* Redundant checks that ensure the function actually returned 0 */ \ |
578 | | asm volatile("cmp r0, #0":::"cc"); \ |
579 | | asm volatile("cmp r0, #0":::"cc"); \ |
580 | | asm volatile("cmp r0, #0":::"cc"); \ |
581 | | asm volatile("bne 4f"); \ |
582 | | asm volatile("cmp r0, #0":::"cc"); \ |
583 | | asm volatile("cmp r0, #0":::"cc"); \ |
584 | | asm volatile("cmp r0, #0":::"cc"); \ |
585 | | asm volatile("bne 4f"); \ |
586 | | asm volatile("cmp r0, #0":::"cc"); \ |
587 | | asm volatile("cmp r0, #0":::"cc"); \ |
588 | | asm volatile("cmp r0, #0":::"cc"); \ |
589 | | asm volatile("bne 4f"); \ |
590 | | asm volatile("cmp r0, #0":::"cc"); \ |
591 | | asm volatile("cmp r0, #0":::"cc"); \ |
592 | | asm volatile("cmp r0, #0":::"cc"); \ |
593 | | asm volatile("bne 4f"); \ |
594 | | /* Check that res = 1, a few times, reading the value from memory */ \ |
595 | | asm volatile("ldr r2, [%0]" ::"r"(p_res)); \ |
596 | | asm volatile("cmp r2, #1":::"cc"); \ |
597 | | asm volatile("cmp r2, #1":::"cc"); \ |
598 | | asm volatile("cmp r2, #1":::"cc"); \ |
599 | | asm volatile("bne 4f"); \ |
600 | | asm volatile("mvn r3, r2":::"r3"); \ |
601 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
602 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
603 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
604 | | asm volatile("bne 4f"); \ |
605 | | asm volatile("ldr r2, [%0]" ::"r"(p_res)); \ |
606 | | asm volatile("cmp r2, #1":::"cc"); \ |
607 | | asm volatile("cmp r2, #1":::"cc"); \ |
608 | | asm volatile("cmp r2, #1":::"cc"); \ |
609 | | asm volatile("bne 4f"); \ |
610 | | asm volatile("mvn r3, r2":::"r3"); \ |
611 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
612 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
613 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
614 | | asm volatile("bne 4f"); \ |
615 | | asm volatile("ldr r2, [%0]" ::"r"(p_res)); \ |
616 | | asm volatile("cmp r2, #1":::"cc"); \ |
617 | | asm volatile("cmp r2, #1":::"cc"); \ |
618 | | asm volatile("cmp r2, #1":::"cc"); \ |
619 | | asm volatile("bne 4f"); \ |
620 | | asm volatile("mvn r3, r2":::"r3"); \ |
621 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
622 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
623 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
624 | | asm volatile("bne 4f"); \ |
625 | | asm volatile("ldr r2, [%0]" ::"r"(p_res)); \ |
626 | | asm volatile("cmp r2, #1":::"cc"); \ |
627 | | asm volatile("cmp r2, #1":::"cc"); \ |
628 | | asm volatile("cmp r2, #1":::"cc"); \ |
629 | | asm volatile("bne 4f"); \ |
630 | | asm volatile("mvn r3, r2":::"r3"); \ |
631 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
632 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
633 | | asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ |
634 | | asm volatile("bne 4f"); \ |
635 | | /* Confirm that the signature is OK */ \ |
636 | | wolfBoot_image_confirm_signature_ok(img); \ |
637 | | asm volatile("4:"); \ |
638 | | asm volatile("nop") \ |
639 | | |
640 | | #elif defined(__ICCARM__) && defined(__IAR_SYSTEMS_ICC__) |
641 | | |
642 | | #define VERIFY_FN(img, p_res, fn, ...) \ |
643 | | do { \ |
644 | | __asm volatile( \ |
645 | | "mov r0, #50\n" \ |
646 | | "mov r0, #50\n" \ |
647 | | "mov r0, #50\n" \ |
648 | | : /* No output operands */ \ |
649 | | : /* No input operands */ \ |
650 | | : "r0" /* Clobbered registers */ \ |
651 | | ); \ |
652 | | void (*confirm_func)(struct wolfBoot_image *) = \ |
653 | | wolfBoot_image_confirm_signature_ok; \ |
654 | | fn(__VA_ARGS__); \ |
655 | | __asm volatile( \ |
656 | | "cmp r0, #0\n" \ |
657 | | "cmp r0, #0\n" \ |
658 | | "cmp r0, #0\n" \ |
659 | | "beq 30f\n" \ |
660 | | "bne 1f\n" \ |
661 | | "bne 1f\n" \ |
662 | | "bne 1f\n" \ |
663 | | "bne 1f\n" \ |
664 | | "b .\n" \ |
665 | | "b .\n" \ |
666 | | "b .\n" \ |
667 | | "30:\n" \ |
668 | | "ldr r2, [%0]\n" \ |
669 | | "cmp r2, #1\n" \ |
670 | | "cmp r2, #1\n" \ |
671 | | "cmp r2, #1\n" \ |
672 | | "beq 31f\n" \ |
673 | | "bne 1f\n" \ |
674 | | "bne 1f\n" \ |
675 | | "bne 1f\n" \ |
676 | | "bne 1f\n" \ |
677 | | "b .\n" \ |
678 | | "b .\n" \ |
679 | | "b .\n" \ |
680 | | "31:\n" \ |
681 | | "mvn r3, r2\n" \ |
682 | | "cmp r3, #0xFFFFFFFE\n" \ |
683 | | "cmp r3, #0xFFFFFFFE\n" \ |
684 | | "cmp r3, #0xFFFFFFFE\n" \ |
685 | | "beq 32f\n" \ |
686 | | "bne 1f\n" \ |
687 | | "bne 1f\n" \ |
688 | | "bne 1f\n" \ |
689 | | "bne 1f\n" \ |
690 | | "b .\n" \ |
691 | | "b .\n" \ |
692 | | "b .\n" \ |
693 | | "32:\n" \ |
694 | | "ldr r2, [%0]\n" \ |
695 | | "cmp r2, #1\n" \ |
696 | | "cmp r2, #1\n" \ |
697 | | "cmp r2, #1\n" \ |
698 | | "beq 33f\n" \ |
699 | | "bne 1f\n" \ |
700 | | "bne 1f\n" \ |
701 | | "bne 1f\n" \ |
702 | | "bne 1f\n" \ |
703 | | "b .\n" \ |
704 | | "b .\n" \ |
705 | | "b .\n" \ |
706 | | "33:\n" \ |
707 | | "mvn r3, r2\n" \ |
708 | | "cmp r3, #0xFFFFFFFE\n" \ |
709 | | "cmp r3, #0xFFFFFFFE\n" \ |
710 | | "cmp r3, #0xFFFFFFFE\n" \ |
711 | | "beq 34f\n" \ |
712 | | "bne 1f\n" \ |
713 | | "bne 1f\n" \ |
714 | | "bne 1f\n" \ |
715 | | "bne 1f\n" \ |
716 | | "b .\n" \ |
717 | | "b .\n" \ |
718 | | "b .\n" \ |
719 | | "34:\n" \ |
720 | | "ldr r2, [%0]\n" \ |
721 | | "cmp r2, #1\n" \ |
722 | | "cmp r2, #1\n" \ |
723 | | "cmp r2, #1\n" \ |
724 | | "beq 35f\n" \ |
725 | | "bne 1f\n" \ |
726 | | "bne 1f\n" \ |
727 | | "bne 1f\n" \ |
728 | | "bne 1f\n" \ |
729 | | "b .\n" \ |
730 | | "b .\n" \ |
731 | | "b .\n" \ |
732 | | "35:\n" \ |
733 | | "mvn r3, r2\n" \ |
734 | | "cmp r3, #0xFFFFFFFE\n" \ |
735 | | "cmp r3, #0xFFFFFFFE\n" \ |
736 | | "cmp r3, #0xFFFFFFFE\n" \ |
737 | | "beq 36f\n" \ |
738 | | "bne 1f\n" \ |
739 | | "bne 1f\n" \ |
740 | | "bne 1f\n" \ |
741 | | "bne 1f\n" \ |
742 | | "b .\n" \ |
743 | | "b .\n" \ |
744 | | "b .\n" \ |
745 | | "36:\n" \ |
746 | | "ldr r2, [%0]\n" \ |
747 | | "cmp r2, #1\n" \ |
748 | | "cmp r2, #1\n" \ |
749 | | "cmp r2, #1\n" \ |
750 | | "beq 37f\n" \ |
751 | | "bne 1f\n" \ |
752 | | "bne 1f\n" \ |
753 | | "bne 1f\n" \ |
754 | | "bne 1f\n" \ |
755 | | "b .\n" \ |
756 | | "b .\n" \ |
757 | | "b .\n" \ |
758 | | "37:\n" \ |
759 | | "mvn r3, r2\n" \ |
760 | | "cmp r3, #0xFFFFFFFE\n" \ |
761 | | "cmp r3, #0xFFFFFFFE\n" \ |
762 | | "cmp r3, #0xFFFFFFFE\n" \ |
763 | | "beq 38f\n" \ |
764 | | "bne 1f\n" \ |
765 | | "bne 1f\n" \ |
766 | | "bne 1f\n" \ |
767 | | "bne 1f\n" \ |
768 | | "b .\n" \ |
769 | | "b .\n" \ |
770 | | "b .\n" \ |
771 | | "38:\n" \ |
772 | | /* Load 'img' into r0 (first argument to the function) */ \ |
773 | | "mov r0, %1\n" \ |
774 | | /* Load the function pointer into r3 */ \ |
775 | | "mov r3, %2\n" \ |
776 | | "blx r3\n"\ |
777 | | "b 2f\n" \ |
778 | | "b .\n" \ |
779 | | "b .\n" \ |
780 | | "b .\n" \ |
781 | | "1:\n" \ |
782 | | "nop\n" \ |
783 | | "2:\n" \ |
784 | | : /* No output operands */ \ |
785 | | : "r"(p_res), "r"(img), "r"(confirm_func) /* Input operands */ \ |
786 | | : "r0", "r2", "r3", "lr" /* Clobbered registers */ \ |
787 | | ); \ |
788 | | } while (0) |
789 | | #endif |
790 | | |
791 | | |
792 | | /** |
793 | | * This macro is only invoked after a successful update version check, prior to |
794 | | * initiating the update installation. |
795 | | * |
796 | | * At this point, wolfBoot thinks that the version check has been successful. |
797 | | * |
798 | | * |
799 | | * The fallback flag (checked with redundancy) causes wolfBoot to skip the |
800 | | * redundant version checks. |
801 | | * |
802 | | * The redundant checks here ensure that the image version is read twice per |
803 | | * each partition, and the two return values are the same. |
804 | | * |
805 | | * |
806 | | * The comparison is also redundant, causing wolfBoot to panic if the update |
807 | | * version is not strictly greater than the current one. |
808 | | * |
809 | | */ |
810 | | #if defined(__GNUC__) |
811 | | |
812 | | #define VERIFY_VERSION_ALLOWED(fb_ok) \ |
813 | | asm volatile( \ |
814 | | "push {r4, r5, r6, r7}\n" \ |
815 | | "mov r0, #0\n" \ |
816 | | "mov r4, #1\n" \ |
817 | | "mov r5, #0\n" \ |
818 | | "mov r6, #2\n" \ |
819 | | "mov r7, #0\n" \ |
820 | | "mov r0, #0\n" \ |
821 | | "mov r4, #1\n" \ |
822 | | "mov r5, #0\n" \ |
823 | | "mov r6, #2\n" \ |
824 | | "mov r7, #0\n" \ |
825 | | "mov r0, %0\n" \ |
826 | | "mov r4, %0\n" \ |
827 | | "cmp r0, #1\n" \ |
828 | | "cmp r0, #1\n" \ |
829 | | "cmp r0, #1\n" \ |
830 | | "beq 20f\n" \ |
831 | | "bne do_check\n" \ |
832 | | "bne do_check\n" \ |
833 | | "bne do_check\n" \ |
834 | | "bne do_check\n" \ |
835 | | "b .\n" \ |
836 | | "b .\n" \ |
837 | | "b .\n" \ |
838 | | "20:\n" \ |
839 | | "cmp r4, #1\n" \ |
840 | | "cmp r4, #1\n" \ |
841 | | "cmp r4, #1\n" \ |
842 | | "beq 21f\n" \ |
843 | | "bne do_check\n" \ |
844 | | "bne do_check\n" \ |
845 | | "bne do_check\n" \ |
846 | | "bne do_check\n" \ |
847 | | "b .\n" \ |
848 | | "b .\n" \ |
849 | | "b .\n" \ |
850 | | "21:\n" \ |
851 | | "cmp r0, r4\n" \ |
852 | | "cmp r0, r4\n" \ |
853 | | "cmp r0, r4\n" \ |
854 | | "beq 22f\n" \ |
855 | | "bne do_check\n" \ |
856 | | "bne do_check\n" \ |
857 | | "bne do_check\n" \ |
858 | | "bne do_check\n" \ |
859 | | "b .\n" \ |
860 | | "b .\n" \ |
861 | | "b .\n" \ |
862 | | "22:\n" \ |
863 | | "cmp r0, #1\n" \ |
864 | | "cmp r0, #1\n" \ |
865 | | "cmp r0, #1\n" \ |
866 | | "beq 23f\n" \ |
867 | | "bne do_check\n" \ |
868 | | "bne do_check\n" \ |
869 | | "bne do_check\n" \ |
870 | | "bne do_check\n" \ |
871 | | "b .\n" \ |
872 | | "b .\n" \ |
873 | | "b .\n" \ |
874 | | "23:\n" \ |
875 | | "b end_check\n" \ |
876 | | "do_check:\n" \ |
877 | | "mov r0, #1\n" \ |
878 | | "mov r0, #1\n" \ |
879 | | "mov r0, #1\n" \ |
880 | | "bl wolfBoot_get_image_version\n" \ |
881 | | "mov r5, r0\n" \ |
882 | | "mov r5, r0\n" \ |
883 | | "mov r5, r0\n" \ |
884 | | "mov r0, #1\n" \ |
885 | | "mov r0, #1\n" \ |
886 | | "mov r0, #1\n" \ |
887 | | "bl wolfBoot_get_image_version\n" \ |
888 | | "mov r7, r0\n" \ |
889 | | "mov r7, r0\n" \ |
890 | | "mov r7, r0\n" \ |
891 | | "cmp r5, r7\n" \ |
892 | | "cmp r5, r7\n" \ |
893 | | "cmp r5, r7\n" \ |
894 | | "beq 24f\n" \ |
895 | | "bne ver_panic\n" \ |
896 | | "bne ver_panic\n" \ |
897 | | "bne ver_panic\n" \ |
898 | | "bne ver_panic\n" \ |
899 | | "b .\n" \ |
900 | | "b .\n" \ |
901 | | "b .\n" \ |
902 | | "24:\n" \ |
903 | | "mov r0, #0\n" \ |
904 | | "mov r0, #0\n" \ |
905 | | "mov r0, #0\n" \ |
906 | | "bl wolfBoot_get_image_version\n" \ |
907 | | "mov r4, r0\n" \ |
908 | | "mov r4, r0\n" \ |
909 | | "mov r4, r0\n" \ |
910 | | "mov r0, #0\n" \ |
911 | | "mov r0, #0\n" \ |
912 | | "mov r0, #0\n" \ |
913 | | "bl wolfBoot_get_image_version\n" \ |
914 | | "mov r6, r0\n" \ |
915 | | "mov r6, r0\n" \ |
916 | | "mov r6, r0\n" \ |
917 | | "cmp r4, r6\n" \ |
918 | | "cmp r4, r6\n" \ |
919 | | "cmp r4, r6\n" \ |
920 | | "beq 25f\n" \ |
921 | | "bne ver_panic\n" \ |
922 | | "bne ver_panic\n" \ |
923 | | "bne ver_panic\n" \ |
924 | | "bne ver_panic\n" \ |
925 | | "b .\n" \ |
926 | | "b .\n" \ |
927 | | "b .\n" \ |
928 | | "25:\n" \ |
929 | | "mov r0, #0\n" \ |
930 | | "mov r0, #0\n" \ |
931 | | "mov r0, #0\n" \ |
932 | | "cmp r4, r5\n" \ |
933 | | "cmp r4, r5\n" \ |
934 | | "cmp r4, r5\n" \ |
935 | | "blo 26f\n" \ |
936 | | "bhs ver_panic\n" \ |
937 | | "bhs ver_panic\n" \ |
938 | | "bhs ver_panic\n" \ |
939 | | "bhs ver_panic\n" \ |
940 | | "b .\n" \ |
941 | | "b .\n" \ |
942 | | "b .\n" \ |
943 | | "26:\n" \ |
944 | | "cmp r6, r7\n" \ |
945 | | "cmp r6, r7\n" \ |
946 | | "cmp r6, r7\n" \ |
947 | | "blo 27f\n" \ |
948 | | "bhs ver_panic\n" \ |
949 | | "bhs ver_panic\n" \ |
950 | | "bhs ver_panic\n" \ |
951 | | "bhs ver_panic\n" \ |
952 | | "b .\n" \ |
953 | | "b .\n" \ |
954 | | "b .\n" \ |
955 | | "27:\n" \ |
956 | | "cmp r4, r5\n" \ |
957 | | "cmp r4, r5\n" \ |
958 | | "cmp r4, r5\n" \ |
959 | | "blo 28f\n" \ |
960 | | "bhs ver_panic\n" \ |
961 | | "bhs ver_panic\n" \ |
962 | | "bhs ver_panic\n" \ |
963 | | "bhs ver_panic\n" \ |
964 | | "b .\n" \ |
965 | | "b .\n" \ |
966 | | "b .\n" \ |
967 | | "28:\n" \ |
968 | | "cmp r6, r7\n" \ |
969 | | "cmp r6, r7\n" \ |
970 | | "cmp r6, r7\n" \ |
971 | | "blo 29f\n" \ |
972 | | "bhs ver_panic\n" \ |
973 | | "bhs ver_panic\n" \ |
974 | | "bhs ver_panic\n" \ |
975 | | "bhs ver_panic\n" \ |
976 | | "b .\n" \ |
977 | | "b .\n" \ |
978 | | "b .\n" \ |
979 | | "29:\n" \ |
980 | | "b end_check\n" \ |
981 | | "ver_panic:\n" \ |
982 | | "b .\n" \ |
983 | | "b .\n" \ |
984 | | "b .\n" \ |
985 | | "b .\n" \ |
986 | | "b .\n" \ |
987 | | "b .\n" \ |
988 | | "b .\n" \ |
989 | | "b .\n" \ |
990 | | "b .\n" \ |
991 | | "b .\n" \ |
992 | | "b .\n" \ |
993 | | "end_check:\n" \ |
994 | | "pop {r4, r5, r6, r7}\n" \ |
995 | | : \ |
996 | | : "r"(fb_ok) \ |
997 | | : "r0", "r4", "r5", "r6", "r7", "lr", "cc", "memory" \ |
998 | | ) |
999 | | |
1000 | | #elif defined(__ICCARM__) && defined(__IAR_SYSTEMS_ICC__) |
1001 | | |
1002 | | #define VERIFY_VERSION_ALLOWED(fb_ok) \ |
1003 | | do { \ |
1004 | | __asm volatile( \ |
1005 | | "push {r4, r5, r6, r7}\n" \ |
1006 | | "mov r0, #0\n" \ |
1007 | | "mov r4, #1\n" \ |
1008 | | "mov r5, #0\n" \ |
1009 | | "mov r6, #2\n" \ |
1010 | | "mov r7, #0\n" \ |
1011 | | "mov r0, #0\n" \ |
1012 | | "mov r4, #1\n" \ |
1013 | | "mov r5, #0\n" \ |
1014 | | "mov r6, #2\n" \ |
1015 | | "mov r7, #0\n" \ |
1016 | | "mov r0, %0\n" \ |
1017 | | "mov r4, %0\n" \ |
1018 | | "cmp r0, #0\n" \ |
1019 | | "cmp r0, #0\n" \ |
1020 | | "cmp r0, #0\n" \ |
1021 | | "beq 4f\n" \ |
1022 | | "bne 6f\n" \ |
1023 | | "bne 6f\n" \ |
1024 | | "bne 6f\n" \ |
1025 | | "bne 6f\n" \ |
1026 | | "b .\n" \ |
1027 | | "b .\n" \ |
1028 | | "b .\n" \ |
1029 | | "6:\n" \ |
1030 | | "cmp r0, #1\n" \ |
1031 | | "cmp r0, #1\n" \ |
1032 | | "cmp r0, #1\n" \ |
1033 | | "beq 4f\n" \ |
1034 | | "bne 1f\n" \ |
1035 | | "bne 1f\n" \ |
1036 | | "bne 1f\n" \ |
1037 | | "bne 1f\n" \ |
1038 | | "b .\n" \ |
1039 | | "b .\n" \ |
1040 | | "b .\n" \ |
1041 | | "4:\n" \ |
1042 | | "cmp r4, #0\n" \ |
1043 | | "cmp r4, #0\n" \ |
1044 | | "cmp r4, #0\n" \ |
1045 | | "beq 5f\n" \ |
1046 | | "bne 7f\n" \ |
1047 | | "bne 7f\n" \ |
1048 | | "bne 7f\n" \ |
1049 | | "bne 7f\n" \ |
1050 | | "b .\n" \ |
1051 | | "b .\n" \ |
1052 | | "b .\n" \ |
1053 | | "7:\n" \ |
1054 | | "cmp r4, #1\n" \ |
1055 | | "cmp r4, #1\n" \ |
1056 | | "cmp r4, #1\n" \ |
1057 | | "beq 5f\n" \ |
1058 | | "bne 1f\n" \ |
1059 | | "bne 1f\n" \ |
1060 | | "bne 1f\n" \ |
1061 | | "bne 1f\n" \ |
1062 | | "b .\n" \ |
1063 | | "b .\n" \ |
1064 | | "b .\n" \ |
1065 | | "5:\n" \ |
1066 | | "cmp r0, #1\n" \ |
1067 | | "cmp r0, #1\n" \ |
1068 | | "cmp r0, #1\n" \ |
1069 | | "beq 8f\n" \ |
1070 | | "bne 1f\n" \ |
1071 | | "bne 1f\n" \ |
1072 | | "bne 1f\n" \ |
1073 | | "bne 1f\n" \ |
1074 | | "b .\n" \ |
1075 | | "b .\n" \ |
1076 | | "b .\n" \ |
1077 | | "8:\n" \ |
1078 | | "cmp r4, #1\n" \ |
1079 | | "cmp r4, #1\n" \ |
1080 | | "cmp r4, #1\n" \ |
1081 | | "beq 9f\n" \ |
1082 | | "bne 1f\n" \ |
1083 | | "bne 1f\n" \ |
1084 | | "bne 1f\n" \ |
1085 | | "bne 1f\n" \ |
1086 | | "b .\n" \ |
1087 | | "b .\n" \ |
1088 | | "b .\n" \ |
1089 | | "9:\n" \ |
1090 | | "cmp r0, r4\n" \ |
1091 | | "cmp r0, r4\n" \ |
1092 | | "cmp r0, r4\n" \ |
1093 | | "beq 10f\n" \ |
1094 | | "bne 1f\n" \ |
1095 | | "bne 1f\n" \ |
1096 | | "bne 1f\n" \ |
1097 | | "bne 1f\n" \ |
1098 | | "b .\n" \ |
1099 | | "b .\n" \ |
1100 | | "b .\n" \ |
1101 | | "10:\n" \ |
1102 | | "cmp r0, #1\n" \ |
1103 | | "cmp r0, #1\n" \ |
1104 | | "cmp r0, #1\n" \ |
1105 | | "beq 11f\n" \ |
1106 | | "bne 1f\n" \ |
1107 | | "bne 1f\n" \ |
1108 | | "bne 1f\n" \ |
1109 | | "bne 1f\n" \ |
1110 | | "b .\n" \ |
1111 | | "b .\n" \ |
1112 | | "b .\n" \ |
1113 | | "11:\n" \ |
1114 | | "b 2f\n" \ |
1115 | | "b .\n" \ |
1116 | | "b .\n" \ |
1117 | | "b .\n" \ |
1118 | | "1:\n" \ |
1119 | | "mov r0, #1\n" \ |
1120 | | "mov r0, #1\n" \ |
1121 | | "mov r0, #1\n" \ |
1122 | | "bl wolfBoot_get_image_version\n" \ |
1123 | | "mov r5, r0\n" \ |
1124 | | "mov r5, r0\n" \ |
1125 | | "mov r5, r0\n" \ |
1126 | | "mov r0, #1\n" \ |
1127 | | "mov r0, #1\n" \ |
1128 | | "mov r0, #1\n" \ |
1129 | | "bl wolfBoot_get_image_version\n" \ |
1130 | | "mov r7, r0\n" \ |
1131 | | "mov r7, r0\n" \ |
1132 | | "mov r7, r0\n" \ |
1133 | | "cmp r5, r7\n" \ |
1134 | | "cmp r5, r7\n" \ |
1135 | | "cmp r5, r7\n" \ |
1136 | | "beq 12f\n" \ |
1137 | | "bne 3f\n" \ |
1138 | | "bne 3f\n" \ |
1139 | | "bne 3f\n" \ |
1140 | | "bne 3f\n" \ |
1141 | | "b .\n" \ |
1142 | | "b .\n" \ |
1143 | | "b .\n" \ |
1144 | | "12:\n" \ |
1145 | | "mov r0, #0\n" \ |
1146 | | "mov r0, #0\n" \ |
1147 | | "mov r0, #0\n" \ |
1148 | | "bl wolfBoot_get_image_version\n" \ |
1149 | | "mov r4, r0\n" \ |
1150 | | "mov r4, r0\n" \ |
1151 | | "mov r4, r0\n" \ |
1152 | | "mov r0, #0\n" \ |
1153 | | "mov r0, #0\n" \ |
1154 | | "mov r0, #0\n" \ |
1155 | | "bl wolfBoot_get_image_version\n" \ |
1156 | | "mov r6, r0\n" \ |
1157 | | "mov r6, r0\n" \ |
1158 | | "mov r6, r0\n" \ |
1159 | | "cmp r4, r6\n" \ |
1160 | | "cmp r4, r6\n" \ |
1161 | | "cmp r4, r6\n" \ |
1162 | | "beq 13f\n" \ |
1163 | | "bne 3f\n" \ |
1164 | | "bne 3f\n" \ |
1165 | | "bne 3f\n" \ |
1166 | | "bne 3f\n" \ |
1167 | | "b .\n" \ |
1168 | | "b .\n" \ |
1169 | | "b .\n" \ |
1170 | | "13:\n" \ |
1171 | | "mov r0, #0\n" \ |
1172 | | "mov r0, #0\n" \ |
1173 | | "mov r0, #0\n" \ |
1174 | | "cmp r4, r5\n" \ |
1175 | | "cmp r4, r5\n" \ |
1176 | | "cmp r4, r5\n" \ |
1177 | | "blo 14f\n" \ |
1178 | | "bhs 3f\n" \ |
1179 | | "bhs 3f\n" \ |
1180 | | "bhs 3f\n" \ |
1181 | | "bhs 3f\n" \ |
1182 | | "b .\n" \ |
1183 | | "b .\n" \ |
1184 | | "b .\n" \ |
1185 | | "14:\n" \ |
1186 | | "cmp r6, r7\n" \ |
1187 | | "cmp r6, r7\n" \ |
1188 | | "cmp r6, r7\n" \ |
1189 | | "blo 15f\n" \ |
1190 | | "bhs 3f\n" \ |
1191 | | "bhs 3f\n" \ |
1192 | | "bhs 3f\n" \ |
1193 | | "bhs 3f\n" \ |
1194 | | "b .\n" \ |
1195 | | "b .\n" \ |
1196 | | "b .\n" \ |
1197 | | "15:\n" \ |
1198 | | "cmp r4, r5\n" \ |
1199 | | "cmp r4, r5\n" \ |
1200 | | "cmp r4, r5\n" \ |
1201 | | "blo 16f\n" \ |
1202 | | "bhs 3f\n" \ |
1203 | | "bhs 3f\n" \ |
1204 | | "bhs 3f\n" \ |
1205 | | "bhs 3f\n" \ |
1206 | | "b .\n" \ |
1207 | | "b .\n" \ |
1208 | | "b .\n" \ |
1209 | | "16:\n" \ |
1210 | | "cmp r6, r7\n" \ |
1211 | | "cmp r6, r7\n" \ |
1212 | | "cmp r6, r7\n" \ |
1213 | | "blo 17f\n" \ |
1214 | | "bhs 3f\n" \ |
1215 | | "bhs 3f\n" \ |
1216 | | "bhs 3f\n" \ |
1217 | | "bhs 3f\n" \ |
1218 | | "b .\n" \ |
1219 | | "b .\n" \ |
1220 | | "b .\n" \ |
1221 | | "17:\n" \ |
1222 | | "b 2f\n" \ |
1223 | | "b .\n" \ |
1224 | | "b .\n" \ |
1225 | | "b .\n" \ |
1226 | | "3:\n" \ |
1227 | | "b .\n" \ |
1228 | | "b .\n" \ |
1229 | | "b .\n" \ |
1230 | | "b .\n" \ |
1231 | | "b .\n" \ |
1232 | | "b .\n" \ |
1233 | | "b .\n" \ |
1234 | | "b .\n" \ |
1235 | | "2:\n" \ |
1236 | | "pop {r4, r5, r6, r7}\n" \ |
1237 | | : /* No output operands */ \ |
1238 | | : "r"(fb_ok) /* Input operands */ \ |
1239 | | : "r0", "r4", "r5", "r6", "r7" /* Clobbered registers */ \ |
1240 | | ); \ |
1241 | | } while (0) |
1242 | | #endif |
1243 | | |
1244 | | |
1245 | | #define CONFIRM_MASK_VALID(id, mask) \ |
1246 | | asm volatile("mov r1, %0" :: "r"(id):"r1"); \ |
1247 | | /* id &= 0x0F */ \ |
1248 | | asm volatile("and.w r1, r1, #15":::"r1"); \ |
1249 | | asm volatile("mov r0, %0" :: "r"(mask):"r0"); \ |
1250 | | asm volatile("movs r2, #1":::"r2"); \ |
1251 | | asm volatile("lsls r2, r1":::"r2","cc"); \ |
1252 | | asm volatile("ands r2, r0":::"r2","cc"); \ |
1253 | | asm volatile("movs r0, #1":::"cc"); \ |
1254 | | asm volatile("lsls r0, r1":::"r0","cc"); \ |
1255 | | asm volatile("cmp r0, r2"); \ |
1256 | | asm volatile("cmp r0, r2"); \ |
1257 | | asm volatile("cmp r0, r2"); \ |
1258 | | asm volatile("bne ."); \ |
1259 | | asm volatile("mov r0, %0" :: "r"(mask)); \ |
1260 | | asm volatile("movs r2, #1":::"r2"); \ |
1261 | | asm volatile("lsls r2, r1":::"r2", "cc"); \ |
1262 | | asm volatile("ands r2, r0":::"r2", "cc"); \ |
1263 | | asm volatile("movs r0, #1":::"r0"); \ |
1264 | | asm volatile("lsls r0, r1":::"r0", "cc"); \ |
1265 | | asm volatile("cmp r0, r2":::"cc"); \ |
1266 | | asm volatile("cmp r0, r2":::"cc"); \ |
1267 | | asm volatile("cmp r0, r2":::"cc"); \ |
1268 | | asm volatile("bne ."); \ |
1269 | | asm volatile("mov r0, %0" :: "r"(mask):"r0"); \ |
1270 | | asm volatile("movs r2, #1":::"r2"); \ |
1271 | | asm volatile("lsls r2, r1":::"r2", "cc"); \ |
1272 | | asm volatile("ands r2, r0":::"r2", "cc"); \ |
1273 | | asm volatile("movs r0, #1":::"r0"); \ |
1274 | | asm volatile("lsls r0, r1":::"r0", "cc"); \ |
1275 | | asm volatile("cmp r0, r2":::"cc"); \ |
1276 | | asm volatile("cmp r0, r2":::"cc"); \ |
1277 | | asm volatile("cmp r0, r2":::"cc"); \ |
1278 | | asm volatile("bne ."); \ |
1279 | | |
1280 | | #else |
1281 | | |
1282 | | struct wolfBoot_image { |
1283 | | uint8_t *hdr; |
1284 | | #ifdef EXT_FLASH |
1285 | | uint8_t *hdr_cache; |
1286 | | #endif |
1287 | | uint8_t *trailer; |
1288 | | uint8_t *sha_hash; |
1289 | | uint8_t *fw_base; |
1290 | | uint32_t fw_size; |
1291 | | uint8_t part; |
1292 | | uint8_t hdr_ok : 1; |
1293 | | uint8_t signature_ok : 1; |
1294 | | uint8_t sha_ok : 1; |
1295 | | uint8_t not_ext : 1; /* image is no longer external */ |
1296 | | }; |
1297 | | |
1298 | | |
1299 | | /* do not warn if this is not used */ |
1300 | | static void UNUSEDFUNCTION wolfBoot_image_confirm_signature_ok( |
1301 | | struct wolfBoot_image *img) |
1302 | 0 | { |
1303 | 0 | img->signature_ok = 1; |
1304 | 0 | } |
1305 | | static void UNUSEDFUNCTION wolfBoot_image_clear_signature_ok( |
1306 | | struct wolfBoot_image *img) |
1307 | 0 | { |
1308 | 0 | img->signature_ok = 0; |
1309 | 0 | } |
1310 | | |
1311 | | #define likely(x) (x) |
1312 | | #define unlikely(x) (x) |
1313 | | |
1314 | | #define VERIFY_FN(img,p_res,fn,...) {\ |
1315 | | int ret = fn(__VA_ARGS__); \ |
1316 | | if ((ret == 0) && (*p_res == 1)) \ |
1317 | | wolfBoot_image_confirm_signature_ok(img); \ |
1318 | | } |
1319 | | |
1320 | | #define RSA_VERIFY_FN(ret,fn,...) \ |
1321 | | ret = fn(__VA_ARGS__); |
1322 | | |
1323 | | #define RSA_VERIFY_HASH(img,digest) \ |
1324 | | if (image_CT_compare(img->sha_hash, digest, WOLFBOOT_SHA_DIGEST_SIZE) == 0) \ |
1325 | | wolfBoot_image_confirm_signature_ok(img); |
1326 | | |
1327 | | #define RSA_PSS_VERIFY_HASH(img, pss_data, pss_data_sz, hash_type) \ |
1328 | | if (wc_RsaPSS_CheckPadding(img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, \ |
1329 | | pss_data, pss_data_sz, hash_type) == 0) \ |
1330 | | wolfBoot_image_confirm_signature_ok(img); |
1331 | | |
1332 | | #define PART_SANITY_CHECK(p) \ |
1333 | | if (((p)->hdr_ok != 1) || ((p)->sha_ok != 1) || ((p)->signature_ok != 1)) \ |
1334 | | wolfBoot_panic() |
1335 | | |
1336 | | #define CONFIRM_MASK_VALID(id, mask) \ |
1337 | | if ((mask & (1UL << id)) != (1UL << id)) \ |
1338 | | wolfBoot_panic() |
1339 | | |
1340 | | #define VERIFY_VERSION_ALLOWED(fb_ok) do{} while(0) /* okay */ |
1341 | | |
1342 | | #endif |
1343 | | |
1344 | | /* Defined in image.c */ |
1345 | | int image_CT_compare(const uint8_t *expected, const uint8_t *actual, |
1346 | | uint32_t len); |
1347 | | int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part); |
1348 | | #ifdef EXT_FLASH |
1349 | | int wolfBoot_open_image_external(struct wolfBoot_image* img, uint8_t part, uint8_t* addr); |
1350 | | #endif |
1351 | | int wolfBoot_open_image_address(struct wolfBoot_image* img, uint8_t* image); |
1352 | | #ifdef WOLFBOOT_SELF_HEADER |
1353 | | int wolfBoot_open_self(struct wolfBoot_image *img); |
1354 | | int wolfBoot_open_self_address(struct wolfBoot_image *img, uint8_t *hdr, |
1355 | | uint8_t *image); |
1356 | | #endif |
1357 | | int wolfBoot_verify_integrity(struct wolfBoot_image *img); |
1358 | | int wolfBoot_verify_authenticity(struct wolfBoot_image *img); |
1359 | | int wolfBoot_set_partition_state(uint8_t part, uint8_t newst); |
1360 | | int wolfBoot_get_update_sector_flag(uint16_t sector, uint8_t *flag); |
1361 | | int wolfBoot_set_update_sector_flag(uint16_t sector, uint8_t newflag); |
1362 | | |
1363 | | #ifdef WOLFBOOT_ELF_FLASH_SCATTER |
1364 | | /* Support for ELF scatter/gather format */ |
1365 | | int wolfBoot_load_flash_image_elf(int part, unsigned long* entry_out, |
1366 | | int ext_flash); |
1367 | | int wolfBoot_check_flash_image_elf(uint8_t part, unsigned long* entry_out); |
1368 | | #endif |
1369 | | |
1370 | | uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset, |
1371 | | uint32_t* sz); |
1372 | | |
1373 | | /* get header type for image */ |
1374 | | uint16_t wolfBoot_get_header(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr); |
1375 | | |
1376 | | /* Find the key slot ID based on the SHA hash of the key. */ |
1377 | | int keyslot_id_by_sha(const uint8_t *hint); |
1378 | | |
1379 | | #ifdef EXT_FLASH |
1380 | | # ifdef PART_BOOT_EXT |
1381 | | # define BOOT_EXT 1 |
1382 | | # else |
1383 | | # define BOOT_EXT 0 |
1384 | | # endif |
1385 | | # ifdef PART_UPDATE_EXT |
1386 | | # define UPDATE_EXT 1 |
1387 | | # else |
1388 | | # define UPDATE_EXT 0 |
1389 | | # endif |
1390 | | # ifdef PART_SWAP_EXT |
1391 | | # define SWAP_EXT 1 |
1392 | | # else |
1393 | | # define SWAP_EXT 0 |
1394 | | # endif |
1395 | | # if defined(WOLFBOOT_SELF_HEADER_EXT) |
1396 | | # define SELF_HEADER_EXT 1 |
1397 | | # else |
1398 | | # define SELF_HEADER_EXT 0 |
1399 | | # endif |
1400 | | # define PARTN_IS_EXT(pn) \ |
1401 | | ((pn == PART_BOOT || pn == PART_DTS_BOOT) ? BOOT_EXT: \ |
1402 | | ((pn == PART_UPDATE || pn == PART_DTS_UPDATE) ? UPDATE_EXT : \ |
1403 | | ((pn == PART_SWAP) ? SWAP_EXT : \ |
1404 | | ((pn == PART_SELF) ? SELF_HEADER_EXT : 0)))) |
1405 | | # define PART_IS_EXT(x) (!(x)->not_ext) && PARTN_IS_EXT(((x)->part)) |
1406 | | |
1407 | | |
1408 | | #if defined(EXT_ENCRYPTED) && (defined(__WOLFBOOT) || defined(UNIT_TEST)) |
1409 | | #define ext_flash_check_write ext_flash_encrypt_write |
1410 | | #define ext_flash_check_read ext_flash_decrypt_read |
1411 | | #else |
1412 | | #define ext_flash_check_write ext_flash_write |
1413 | | #define ext_flash_check_read ext_flash_read |
1414 | | #endif |
1415 | | |
1416 | | static inline int wb_flash_erase(struct wolfBoot_image *img, uint32_t off, |
1417 | | uint32_t size) |
1418 | | { |
1419 | | if (PART_IS_EXT(img)) |
1420 | | return ext_flash_erase((uintptr_t)(img->hdr) + off, size); |
1421 | | else |
1422 | | return hal_flash_erase((uintptr_t)(img->hdr) + off, size); |
1423 | | } |
1424 | | |
1425 | | static inline int wb_flash_write(struct wolfBoot_image *img, uint32_t off, |
1426 | | const void *data, uint32_t size) |
1427 | | { |
1428 | | if (PART_IS_EXT(img)) |
1429 | | return ext_flash_check_write((uintptr_t)(img->hdr) + off, data, size); |
1430 | | else |
1431 | | return hal_flash_write((uintptr_t)(img->hdr) + off, data, size); |
1432 | | } |
1433 | | |
1434 | | static inline int wb_flash_write_verify_word(struct wolfBoot_image *img, |
1435 | | uint32_t off, uint32_t word) |
1436 | | { |
1437 | | int ret; |
1438 | | volatile uint32_t copy; |
1439 | | if (PART_IS_EXT(img)) |
1440 | | { |
1441 | | ext_flash_check_read((uintptr_t)(img->hdr) + off, (void *)©, |
1442 | | sizeof(uint32_t)); |
1443 | | while (copy != word) { |
1444 | | ret = ext_flash_check_write((uintptr_t)(img->hdr) + off, |
1445 | | (void *)&word, sizeof(uint32_t)); |
1446 | | if (ret < 0) |
1447 | | return ret; |
1448 | | ext_flash_check_read((uintptr_t)(img->hdr) + off, (void *)©, |
1449 | | sizeof(uint32_t)); |
1450 | | } |
1451 | | } else { |
1452 | | volatile uint32_t *pcopy = (volatile uint32_t*)(img->hdr + off); |
1453 | | while(*pcopy != word) { |
1454 | | hal_flash_write((uintptr_t)pcopy, (void *)&word, sizeof(uint32_t)); |
1455 | | } |
1456 | | } |
1457 | | return 0; |
1458 | | } |
1459 | | |
1460 | | |
1461 | | #else |
1462 | | |
1463 | | # define SWAP_EXT (0) |
1464 | | # define BOOT_EXT (0) |
1465 | | # define UPDATE_EXT (0) |
1466 | | # define PART_IS_EXT(x) (0) |
1467 | | # define PARTN_IS_EXT(x) (0) |
1468 | | # define wb_flash_erase(im, of, siz) \ |
1469 | | hal_flash_erase(((uintptr_t)(((im)->hdr)) + of), siz) |
1470 | | # define wb_flash_write(im, of, dat, siz) \ |
1471 | | hal_flash_write(((uintptr_t)((im)->hdr)) + of, dat, siz) |
1472 | | |
1473 | | #endif /* EXT_FLASH */ |
1474 | | |
1475 | | /* -- Image Formats -- */ |
1476 | | /* Legacy U-Boot Image */ |
1477 | | #ifdef BIG_ENDIAN_ORDER |
1478 | | #define UBOOT_IMG_HDR_MAGIC 0x27051956UL |
1479 | | #else |
1480 | | #define UBOOT_IMG_HDR_MAGIC 0x56190527UL |
1481 | | #endif |
1482 | | #define UBOOT_IMG_HDR_SZ 64 |
1483 | | |
1484 | | /* --- Flattened Device Tree Blob */ |
1485 | | #ifdef MMU |
1486 | | #include "fdt.h" |
1487 | | #endif |
1488 | | |
1489 | | #ifndef EXT_ENCRYPTED |
1490 | | #define WOLFBOOT_MAX_SPACE (WOLFBOOT_PARTITION_SIZE - \ |
1491 | | (TRAILER_SKIP + sizeof(uint32_t) + \ |
1492 | | ((WOLFBOOT_PARTITION_SIZE + 1) / (WOLFBOOT_SECTOR_SIZE * 8)))) |
1493 | | #else |
1494 | | #define WOLFBOOT_MAX_SPACE (WOLFBOOT_PARTITION_SIZE - ENCRYPT_TMP_SECRET_OFFSET) |
1495 | | #endif |
1496 | | |
1497 | | #ifdef __cplusplus |
1498 | | } |
1499 | | #endif |
1500 | | |
1501 | | #endif /* !IMAGE_H */ |