blob: bfa12d219cab72a9fb044bc8afe1a99d6e5fbbe6 [file] [log] [blame]
Christopher Collins92ea77f2016-12-12 15:59:26 -08001#
2# Licensed to the Apache Software Foundation (ASF) under one
3# or more contributor license agreements. See the NOTICE file
4# distributed with this work for additional information
5# regarding copyright ownership. The ASF licenses this file
6# to you under the Apache License, Version 2.0 (the
7# "License"); you may not use this file except in compliance
8# with the License. You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing,
13# software distributed under the License is distributed on an
14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15# KIND, either express or implied. See the License for the
16# specific language governing permissions and limitations
17# under the License.
18#
19
20****** BOOT LOADER
21
22*** SUMMARY
23
24The Mynewt bootloader comprises two packages:
25
26 * The bootutil library (boot/bootutil)
27 * The boot application (apps/boot)
28
29The bootutil library performs most of the functions of a boot loader. In
30particular, the piece that is missing is the final step of actually jumping to
31the main image. This last step is instead implemented by the boot application.
32Boot loader functionality is separated in this manner to enable unit testing of
33the boot loader. A library can be unit tested, but an application can't.
34Therefore, functionality is delegated to the bootutil library when possible.
35
36*** LIMITATIONS
37
38The boot loader currently only supports images with the following
39characteristics:
40 * Built to run from flash.
41 * Build to run from a fixed location (i.e., not position-independent).
42
43*** IMAGE FORMAT
44
45The following definitions describe the image format.
46
47#define IMAGE_MAGIC 0x96f3b83c
48
49#define IMAGE_HEADER_SIZE 32
50
51struct image_version {
52 uint8_t iv_major;
53 uint8_t iv_minor;
54 uint16_t iv_revision;
55 uint32_t iv_build_num;
56};
57
58/** Image header. All fields are in little endian byte order. */
59struct image_header {
60 uint32_t ih_magic;
61 uint16_t ih_tlv_size; /* Combined size of trailing TLVs (bytes). */
62 uint8_t ih_key_id; /* Which key image is signed with (0xff=unsigned). */
63 uint8_t _pad1;
64 uint16_t ih_hdr_size; /* Size of image header (bytes). */
65 uint16_t _pad2;
66 uint32_t ih_img_size; /* Does not include header. */
67 uint32_t ih_flags; /* IMAGE_F_[...] */
68 struct image_version ih_ver;
69 uint32_t _pad3;
70};
71
72/** Image trailer TLV format. All fields in little endian. */
73struct image_tlv {
74 uint8_t it_type; /* IMAGE_TLV_[...]. */
75 uint8_t _pad;
76 uint16_t it_len /* Data length (not including TLV header). */
77};
78
79/*
80 * Image header flags.
81 */
82#define IMAGE_F_PIC 0x00000001 /* Not currently supported. */
83#define IMAGE_F_SHA256 0x00000002 /* Image contains hash TLV */
84#define IMAGE_F_PKCS15_RSA2048_SHA256 0x00000004 /* PKCS15 w/RSA and SHA */
85#define IMAGE_F_ECDSA224_SHA256 0x00000008 /* ECDSA256 over SHA256 */
86#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
87
88/*
89 * Image trailer TLV types.
90 */
91#define IMAGE_TLV_SHA256 1 /* SHA256 of image hdr and body */
92#define IMAGE_TLV_RSA2048 2 /* RSA2048 of hash output */
93#define IMAGE_TLV_ECDSA224 3 /* ECDSA of hash output */
94
95Optional type-length-value records (TLVs) containing image metadata are placed
96after the end of the image.
97
98The ih_hdr_size field indicates the length of the header, and therefore the
99offset of the image itself. This field provides for backwards compatibility in
100case of changes to the format of the image header.
101
102*** FLASH MAP
103
104A Mynewt device's flash is partitioned according to its _flash map_. At a high
105level, the flash map maps numeric IDs to _flash areas_. A flash area is a
106region of disk with the following properties:
107 (1) An area can be fully erased without affecting any other areas.
108 (2) A write to one area does not restrict writes to other areas.
109
110The boot loader uses the following flash areas:
111
112#define FLASH_AREA_BOOTLOADER 0
113#define FLASH_AREA_IMAGE_0 1
114#define FLASH_AREA_IMAGE_1 2
115#define FLASH_AREA_IMAGE_SCRATCH 3
116
117*** IMAGE SLOTS
118
119A portion of the flash memory is partitioned into two image slots: a primary
120slot (0) and a secondary slot (1). The boot loader will only run an image from
121the primary slot, so images must be built such that they can run from that
122fixed location in flash. If the boot loader needs to run the image resident in
123the secondary slot, it must swap the two images in flash prior to booting.
124
125In addition to the two image slots, the boot loader requires a scratch area to
126allow for reliable image swapping.
127
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800128*** BOOT STATES
129
130Logically, you can think of a pair of values associated with each image slot:
131pending and confirmed. On startup, the boot loader determines the state of the
132device by inspecting each pair of values. These values have the following
133meanings:
134
135* pending: Indicates whether the image should be used on the next reboot; can
136 hold one of three values:
137 " " (unset): Don't use image on next boot
138 "T" (temporary): Use image on next boot; absent subsequent confirm command,
139 revert to original image on second reboot.
140 "P" (permanent): Use image on next boot and all subsequent boots
141
142* confirmed: always use image unless excluded by a test image.
143
144In English, when the user wants to run the secondary image, they set the
145pending flag for the second slot and reboot the device. On startup, the boot
146loader will swap the two images in flash, clear the secondary slot's pending
147flag, and run the newly-copied image in slot 0. If the user set the pending
148flag to "temporary," then this is only a temporary state; if the device reboots
149again, the boot loader swaps the images back to their original slots and boots
150into the original image. If the user doesn't want to revert to the original
151state, they can make the current state permanent by setting the confirmed flag
152in slot 0.
153
154Switching to an alternate image is a two-step process (set + confirm) to
155prevent a device from becoming "bricked" by bad firmware. If the device
156crashes immediately upon booting the second image, the boot loader reverts to
157the working image, rather than repeatedly rebooting into the bad image.
158
159Alternatively, if the user is confident that the second image is good, they can
160set and confirm in a single action by setting the pending flag to "permanent."
161
162The following set of tables illustrate the four possible states that the device
163can be in:
164
165 | slot-0 | slot-1 |
166 ---------------+--------+--------|
167 pending | | |
168 confirmed | X | |
169 ---------------+--------+--------'
170 Image 0 confirmed; |
171 No change on reboot |
172 ---------------------------------'
173
174 | slot-0 | slot-1 |
175 ---------------+--------+--------|
176 pending | | T |
177 confirmed | X | |
178 ---------------+--------+--------'
179 Image 0 confirmed; |
180 Test image 1 on next reboot |
181 ---------------------------------'
182
183 | slot-0 | slot-1 |
184 ---------------+--------+--------|
185 pending | | P |
186 confirmed | X | |
187 ---------------+--------+--------'
188 Image 0 confirmed; |
189 Use image 1 permanently on boot |
190 ---------------------------------'
191
192 | slot-0 | slot-1 |
193 ---------------+--------+--------|
194 pending | | |
195 confirmed | | X |
196 ---------------+--------+--------'
197 Testing image 0; |
198 Revert to image 1 on next reboot |
199 ---------------------------------'
200
Christopher Collins92ea77f2016-12-12 15:59:26 -0800201*** BOOT VECTOR
202
203At startup, the boot loader determines which of the above three states the
204device is in by inspecting the boot vector. The boot vector consists of two
205records (called "image trailers"), one written at the end of each image slot.
206An image trailer has the following structure:
207
208 0 1 2 3
209 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
210 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211 ~ MAGIC (16 octets) ~
212 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
213 ~ ~
214 ~ Swap status (128 * min-write-size * 3) ~
215 ~ ~
216 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
217 | Copy done | 0xff padding (up to min-write-sz - 1) ~
218 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
219 | Image OK | 0xff padding (up to min-write-sz - 1) ~
220 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
221
222These records are at the end of each image slot. The offset immediately
223following such a record represents the start of the next flash area.
224
225Note: "min-write-size" is a property of the flash hardware. If the hardware
226allows individual bytes to be written at arbitrary addresses, then
227min-write-size is 1. If the hardware only allows writes at even addresses,
228then min-write-size is 2, and so on.
229
230The fields are defined as follows:
231
2321. MAGIC: The following 16 bytes, written in host-byte-order:
233
234 const uint32_t boot_img_magic[4] = {
235 0xf395c277,
236 0x7fefd260,
237 0x0f505235,
238 0x8079b62c,
239 };
240
2412. Swap status: A series of single-byte records. Each record corresponds to a
242flash sector in an image slot. A swap status byte indicate the location of
243the corresponding sector data. During an image swap, image data is moved one
244sector at a time. The swap status is necessary for resuming a swap operation
245if the device rebooted before a swap operation completed.
246
2473. Copy done: A single byte indicating whether the image in this slot is
248complete (0x01=done; 0xff=not done).
249
2504. Image OK: A single byte indicating whether the image in this slot has been
251confirmed as good by the user (0x01=confirmed; 0xff=not confirmed).
252
253The boot vector records are structured around the limitations imposed by flash
254hardware. As a consequence, they do not have a very intuitive design, and it
255is difficult to get a sense of the state of the device just by looking at the
256boot vector. It is better to map all the possible vector states to the three
257states described above via a set of tables. These tables are reproduced below.
258In these tables, the "pending" and "confirmed" flags are shown for illustrative
259purposes; they are not actually present in the boot vector.
260
261
262 State I
263 | slot-0 | slot-1 |
264 -----------------+--------+--------|
265 magic | Unset | Unset |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800266 image-ok | Any | Any |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800267 -----------------+--------+--------'
268 pending | | |
269 confirmed | X | |
270 -----------------+--------+--------'
271 swap: none |
272 -----------------------------------'
273
274
275 State II
276 | slot-0 | slot-1 |
277 -----------------+--------+--------|
278 magic | Any | Good |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800279 image-ok | Any | Unset |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800280 -----------------+--------+--------'
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800281 pending | | T |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800282 confirmed | X | |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800283 -----------------+--------+--------'
284 swap: test |
285 -----------------------------------'
286
Christopher Collins92ea77f2016-12-12 15:59:26 -0800287
288 State III
289 | slot-0 | slot-1 |
290 -----------------+--------+--------|
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800291 magic | Any | Good |
292 image-ok | Any | 0x01 |
293 -----------------+--------+--------'
294 pending | | P |
295 confirmed | X | |
296 -----------------+--------+--------'
297 swap: permanent |
298 -----------------------------------'
299
300
301 State IV
302 | slot-0 | slot-1 |
303 -----------------+--------+--------|
Christopher Collins92ea77f2016-12-12 15:59:26 -0800304 magic | Good | Unset |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800305 image-ok | 0xff | Any |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800306 -----------------+--------+--------'
307 pending | | |
308 confirmed | | X |
309 -----------------+--------+--------'
310 swap: revert (test image running) |
311 -----------------------------------'
312
313
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800314 State V
Christopher Collins92ea77f2016-12-12 15:59:26 -0800315 | slot-0 | slot-1 |
316 -----------------+--------+--------|
317 magic | Good | Unset |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800318 image-ok | 0x01 | Any |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800319 -----------------+--------+--------'
320 pending | | |
321 confirmed | X | |
322 -----------------+--------+--------'
323 swap: none (confirmed test image) |
324 -----------------------------------'
325
326*** HIGH-LEVEL OPERATION
327
328With the terms defined, we can now explore the boot loader's operation. First,
329a high-level overview of the boot process is presented. Then, the following
330sections describe each step of the process in more detail.
331
332Procedure:
333
334A. Inspect swap status region; is an interrupted swap is being resumed?
335 Yes: Complete the partial swap operation; skip to step C.
336 No: Proceed to step B.
337
338B. Insect boot vector; is a swap requested?
339 Yes.
340 1. Is the requested image valid (integrity and security check)?
341 Yes.
342 a. Perform swap operation.
343 b. Persist completion of swap procedure to boot vector.
344 c. Proceed to step C.
345 No.
346 a. Erase invalid image.
347 b. Persist failure of swap procedure to boot vector.
348 c. Proceed to step C.
349 No: Proceed to step C.
350
351C. Boot into image in slot 0.
352
Christopher Collins92ea77f2016-12-12 15:59:26 -0800353
354
355*** IMAGE SWAPPING
356
357The boot loader swaps the contents of the two image slots for two reasons:
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800358 * User has issued a "set pending" operation; the image in slot-1 should be
359 run once (state II) or repeatedly (state III), depending on whether a
360 permanent swap was specified.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800361 * Test image rebooted without being confirmed; the boot loader should
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800362 revert to the original image currently in slot-1 (state IV).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800363
364If the boot vector indicates that the image in the secondary slot should be
365run, the boot loader needs to copy it to the primary slot. The image currently
366in the primary slot also needs to be retained in flash so that it can be used
367later. Furthermore, both images need to be recoverable if the boot loader
368resets in the middle of the swap operation. The two images are swapped
369according to the following procedure:
370
371 1. Determine how many flash sectors each image slot consists of. This
372 number must be the same for both slots.
373 2. Iterate the list of sector indices in descending order (i.e., starting
374 with the greatest index); current element = "index".
375 b. Erase scratch area.
376 c. Copy slot0[index] to scratch area.
377 d. Write updated swap status (i).
378
379 e. Erase slot1[index]
380 f. Copy slot0[index] to slot1[index]
381 - If these are the last sectors (i.e., first swap being perfomed),
382 copy the full sector *except* the image trailer.
383 - Else, copy entire sector contents.
384 g. Write updated swap status (ii).
385
386 h. Erase slot0[index].
387 i. Copy scratch area slot0[index].
388 j. Write updated swap status (iii).
389
390 3. Persist completion of swap procedure to slot 0 image trailer.
391
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800392The additional caveats in step 2f are necessary so that the slot 1 image
393trailer can be written by the user at a later time. With the image trailer
394unwritten, the user can test the image in slot 1 (i.e., transition to state
395II).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800396
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800397The particulars of step 3 vary depending on whether an image is being tested,
398permanently used, or reverted:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800399 * test:
400 o Write slot0.copy_done = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800401 (swap caused the following values to be written:
402 slot0.magic = BOOT_MAGIC
403 slot0.image_ok = Unset)
404 (should now be in state IV)
405
406 * permanent:
407 o Write slot0.copy_done = 1
408 (swap caused the following values to be written:
409 slot0.magic = BOOT_MAGIC
410 slot0.image_ok = 0x01)
411 (should now be in state V)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800412
413 * revert:
414 o Write slot0.magic = BOOT_MAGIC
415 o Write slot0.copy_done = 1
416 o Write slot0.image_ok = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800417 (should now be in state V)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800418
419*** SWAP STATUS
420
421The swap status region allows the boot loader to recover in case it restarts in
422the middle of an image swap operation. The swap status region consists of a
423series of single-byte records. These records are written independently, and
424therefore must be padded according to the minimum write size imposed by the
425flash hardware. In the below figure, a min-write-size of 1 is assumed for
426simplicity. The structure of the swap status region is illustrated below. In
427this figure, a min-write-size of 1 is assumed for simplicity.
428
429 0 1 2 3
430 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
431 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
432 |sec127,state 0 |sec127,state 1 |sec127,state 2 |sec126,state 0 |
433 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
434 |sec126,state 1 |sec126,state 2 |sec125,state 0 |sec125,state 1 |
435 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
436 |sec125,state 2 | |
437 +-+-+-+-+-+-+-+-+ +
438 ~ ~
439 ~ [Records for indices 124 through 1 ~
440 ~ ~
441 ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
442 ~ |sec000,state 0 |sec000,state 1 |sec000,state 2 |
443 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
444
445The above is probably not helpful at all; here is a description in English.
446
447Each image slot is partitioned into a sequence of flash sectors. If we were to
448enumerate the sectors in a single slot, starting at 0, we would have a list of
449sector indices. Since there are two image slots, each sector index would
450correspond to a pair of sectors. For example, sector index 0 corresponds to
451the first sector in slot 0 and the first sector in slot 1. Furthermore, we
452impose a limit of 128 indices. If an image slot consists of more than 128
453sectors, the flash layout is not compatible with this boot loader. Finally,
454reverse the list of indices such that the list starts with index 127 and ends
455with 0. The swap status region is a representation of this reversed list.
456
457During a swap operation, each sector index transitions through four separate
458states:
459 0. slot 0: image 0, slot 1: image 1, scratch: N/A
460 1. slot 0: image 0, slot 1: N/A, scratch: image 1 (1->s, erase 1)
461 2. slot 0: N/A, slot 1: image 0, scratch: image 1 (0->1, erase 0)
462 3. slot 0: image 1, slot 1: image 0, scratch: N/A (s->0)
463
464Each time a sector index transitions to a new state, the boot loader writes a
465record to the swap status region. Logically, the boot loader only needs one
466record per sector index to keep track of the current swap state. However, due
467to limitations imposed by flash hardware, a record cannot be overwritten when
468an index's state changes. To solve this problem, the boot loader uses three
469records per sector index rather than just one.
470
471Each sector-state pair is represented as a set of three records. The record
472values map to the above four states as follows
473
474 | rec0 | rec1 | rec2
475 --------+------+------+------
476 state 0 | 0xff | 0xff | 0xff
477 state 1 | 0x01 | 0xff | 0xff
478 state 2 | 0x01 | 0x02 | 0xff
479 state 3 | 0x01 | 0x02 | 0x03
480
481The swap status region can accommodate 128 sector indices. Hence, the size of
482the region, in bytes, is 128 * min-write-size * 3. The number 128 is chosen
483somewhat arbitrarily and will likely be made configurable. The only
484requirement for the index count is that is is great enough to account for a
485maximum-sized image (i.e., at least as great as the total sector count in an
486image slot). If a device's image slots use less than 128 sectors, the first
487record that gets written will be somewhere in the middle of the region. For
488example, if a slot uses 64 sectors, the first sector index that gets swapped is
48963, which corresponds to the exact halfway point within the region.
490
491
492*** RESET RECOVERY
493
494If the boot loader resets in the middle of a swap operation, the two images may
495be discontiguous in flash. Bootutil recovers from this condition by using the
496boot vector to determine how the image parts are distributed in flash.
497
498The first step is determine where the relevant swap status region is located.
499Because this region is embedded within the image slots, its location in flash
500changes during a swap operation. The below set of tables map boot vector
501contents to swap status location. In these tables, the "source" field
502indicates where the swap status region is located.
503
504 | slot-0 | scratch |
505 ----------+------------+------------|
506 magic | Good | Any |
507 copy-done | 0x01 | N/A |
508 ----------+------------+------------'
509 source: none |
510 ------------------------------------'
511
512 | slot-0 | scratch |
513 ----------+------------+------------|
514 magic | Good | Any |
515 copy-done | 0xff | N/A |
516 ----------+------------+------------'
517 source: slot 0 |
518 ------------------------------------'
519
520 | slot-0 | scratch |
521 ----------+------------+------------|
522 magic | Any | Good |
523 copy-done | Any | N/A |
524 ----------+------------+------------'
525 source: scratch |
526 ------------------------------------'
527
528 | slot-0 | scratch |
529 ----------+------------+------------|
530 magic | Unset | Any |
531 copy-done | 0xff | N/A |
532 ----------+------------+------------|
533 source: varies |
534 ------------------------------------+------------------------------+
535 This represents one of two cases: |
536 o No swaps ever (no status to read, so no harm in checking). |
537 o Mid-revert; status in slot 0. |
538 -------------------------------------------------------------------'
539
540
541If the swap status region indicates that the images are not contiguous,
542bootutil completes the swap operation that was in progress when the system was
543reset. In other words, it applies the procedure defined in the previous
544section, moving image 1 into slot 0 and image 0 into slot 1. If the boot
545status file indicates that an image part is present in the scratch area, this
546part is copied into the correct location by starting at step e or step h in the
547area-swap procedure, depending on whether the part belongs to image 0 or image
5481.
549
550After the swap operation has been completed, the boot loader proceeds as though
551it had just been started.
552
553*** INTEGRITY CHECK
554
555An image is checked for integrity immediately before it gets copied into the
556primary slot. If the boot loader doesn't perform an image swap, then it
557doesn't perform an integrity check.
558
559During the integrity check, the boot loader verifies the following aspects of
560an image:
561 * 32-bit magic number must be correct (0x96f3b83c).
562 * Image must contain a SHA256 TLV.
563 * Calculated SHA256 must matche SHA256 TLV contents.
564 * Image *may* contain a signature TLV. If it does, its contents must be
565 verifiable using a key embedded in the boot loader.
566
567*** SECURITY
568
569As indicated above, the final step of the integrity check is signature
570verification. The boot loader can have one or more public keys embedded in it
571at build time. During signature verification, the boot loader verifies that an
572image was signed with a private key that corresponds to one of its public keys.
573The image signature TLV indicates the index of the key that is has been signed
574with. The boot loader uses this index to identify the corresponding public
575key.
576
577For information on embedding public keys in the boot loader, as well as
578producing signed images, see: boot/bootutil/signed_images.md