@@ -50,6 +50,10 @@ BOOT_LOG_MODULE_DECLARE(mcuboot);
5050#include "bootutil/mcuboot_uuid.h"
5151#endif /* MCUBOOT_UUID_VID || MCUBOOT_UUID_CID */
5252
53+ #ifdef MCUBOOT_MANIFEST_UPDATES
54+ #include "bootutil/mcuboot_manifest.h"
55+ #endif /* MCUBOOT_MANIFEST_UPDATES */
56+
5357#ifdef MCUBOOT_ENC_IMAGES
5458#include "bootutil/enc_key.h"
5559#endif
@@ -206,7 +210,7 @@ bootutil_img_validate(struct boot_loader_state *state,
206210{
207211#if (defined(EXPECTED_KEY_TLV ) && defined(MCUBOOT_HW_KEY )) || \
208212 (defined(EXPECTED_SIG_TLV ) && defined(MCUBOOT_BUILTIN_KEY )) || \
209- defined(MCUBOOT_HW_ROLLBACK_PROT ) || \
213+ defined(MCUBOOT_HW_ROLLBACK_PROT ) || defined( MCUBOOT_MANIFEST_UPDATES ) || \
210214 defined(MCUBOOT_UUID_VID ) || defined(MCUBOOT_UUID_CID )
211215 int image_index = (state == NULL ? 0 : BOOT_CURR_IMG (state ));
212216#endif
@@ -244,6 +248,11 @@ bootutil_img_validate(struct boot_loader_state *state,
244248 uint32_t img_security_cnt = 0 ;
245249 FIH_DECLARE (security_counter_valid , FIH_FAILURE );
246250#endif
251+ #ifdef MCUBOOT_MANIFEST_UPDATES
252+ bool manifest_found = false;
253+ bool manifest_valid = false;
254+ uint8_t slot = (flash_area_get_id (fap ) == FLASH_AREA_IMAGE_SECONDARY (image_index ) ? 1 : 0 );
255+ #endif
247256#ifdef MCUBOOT_UUID_VID
248257 struct image_uuid img_uuid_vid = {0x00 };
249258 FIH_DECLARE (uuid_vid_valid , FIH_FAILURE );
@@ -356,6 +365,69 @@ bootutil_img_validate(struct boot_loader_state *state,
356365 goto out ;
357366 }
358367
368+ #ifdef MCUBOOT_MANIFEST_UPDATES
369+ if (image_index == MCUBOOT_MANIFEST_IMAGE_NUMBER ) {
370+ if (!state -> manifest_valid [slot ]) {
371+ /* Manifest TLV must be processed before any of the image's hash TLV. */
372+ BOOT_LOG_ERR ("bootutil_img_validate: image rejected, manifest not found before "
373+ "image %d hash" , image_index );
374+ rc = -1 ;
375+ goto out ;
376+ }
377+ /* Manifest image does not have hash in the manifest. */
378+ image_hash_valid = 1 ;
379+ break ;
380+ }
381+ #if defined(MCUBOOT_SWAP_USING_SCRATCH ) || defined(MCUBOOT_SWAP_USING_MOVE ) || \
382+ defined(MCUBOOT_SWAP_USING_OFFSET )
383+ state -> matching_manifest [image_index ][slot ] = BOOT_SLOT_NONE ;
384+ /* Try to match with the primary manifest first. */
385+ if (state -> manifest_valid [BOOT_SLOT_PRIMARY ]) {
386+ if (bootutil_verify_manifest_image_hash (& state -> manifest [BOOT_SLOT_PRIMARY ], hash ,
387+ image_index )) {
388+ state -> matching_manifest [image_index ][slot ] = BOOT_SLOT_PRIMARY ;
389+ }
390+ }
391+
392+ /* Try to match with the secondary manifest if not matched with the primary. */
393+ if (state -> matching_manifest [image_index ][slot ] == BOOT_SLOT_NONE &&
394+ state -> manifest_valid [BOOT_SLOT_SECONDARY ]) {
395+ if (bootutil_verify_manifest_image_hash (& state -> manifest [BOOT_SLOT_SECONDARY ], hash ,
396+ image_index )) {
397+ state -> matching_manifest [image_index ][slot ] = BOOT_SLOT_SECONDARY ;
398+ }
399+ }
400+
401+ /* No matching manifest found. */
402+ if (state -> matching_manifest [image_index ][slot ] == BOOT_SLOT_NONE ) {
403+ BOOT_LOG_ERR (
404+ "bootutil_img_validate: image rejected, no valid manifest for image %d slot %d" ,
405+ image_index , slot );
406+ rc = -1 ;
407+ goto out ;
408+ } else {
409+ BOOT_LOG_INF ("bootutil_img_validate: image %d slot %d matches manifest in slot %d" ,
410+ image_index , slot , state -> matching_manifest [image_index ][slot ]);
411+ }
412+ #else /* MCUBOOT_SWAP_USING_SCRATCH || MCUBOOT_SWAP_USING_MOVE || MCUBOOT_SWAP_USING_OFFSET */
413+ /* Manifest image for a given slot must precede any of other images. */
414+ if (!state -> manifest_valid [slot ]) {
415+ /* Manifest TLV must be processed before any of the image's hash TLV. */
416+ BOOT_LOG_ERR ("bootutil_img_validate: image rejected, no valid manifest for slot %d" ,
417+ slot );
418+ rc = -1 ;
419+ goto out ;
420+ }
421+
422+ /* Any image, not described by the manifest is considered as invalid. */
423+ if (!bootutil_verify_manifest_image_hash (& state -> manifest [slot ], hash , image_index )) {
424+ BOOT_LOG_ERR (
425+ "bootutil_img_validate: image rejected, hash does not match manifest contents" );
426+ FIH_SET (fih_rc , FIH_FAILURE );
427+ goto out ;
428+ }
429+ #endif /* MCUBOOT_SWAP_USING_SCRATCH || MCUBOOT_SWAP_USING_MOVE || MCUBOOT_SWAP_USING_OFFSET */
430+ #endif /* MCUBOOT_MANIFEST_UPDATES */
359431 image_hash_valid = 1 ;
360432 break ;
361433 }
@@ -484,6 +556,43 @@ bootutil_img_validate(struct boot_loader_state *state,
484556 break ;
485557 }
486558#endif /* MCUBOOT_HW_ROLLBACK_PROT */
559+ #ifdef MCUBOOT_MANIFEST_UPDATES
560+ case IMAGE_TLV_MANIFEST :
561+ {
562+ /* There can be only one manifest and must be a part of image with specific index. */
563+ if (manifest_found || image_index != MCUBOOT_MANIFEST_IMAGE_NUMBER ||
564+ len != sizeof (struct mcuboot_manifest )) {
565+ BOOT_LOG_ERR (
566+ "bootutil_img_validate: image %d slot %d rejected, unexpected manifest TLV" ,
567+ image_index , slot );
568+ rc = -1 ;
569+ goto out ;
570+ }
571+
572+ manifest_found = true;
573+
574+ rc = LOAD_IMAGE_DATA (hdr , fap , off , & state -> manifest [slot ],
575+ sizeof (struct mcuboot_manifest ));
576+ if (rc ) {
577+ BOOT_LOG_ERR ("bootutil_img_validate: slot %d rejected, unable to load manifest" ,
578+ slot );
579+ goto out ;
580+ }
581+
582+ manifest_valid = bootutil_verify_manifest (& state -> manifest [slot ]);
583+ if (!manifest_valid ) {
584+ BOOT_LOG_ERR ("bootutil_img_validate: slot %d rejected, invalid manifest contents" ,
585+ slot );
586+ rc = -1 ;
587+ goto out ;
588+ }
589+
590+ /* The image's manifest has been successfully verified. */
591+ state -> manifest_valid [slot ] = true;
592+ BOOT_LOG_INF ("bootutil_img_validate: slot %d manifest verified" , slot );
593+ break ;
594+ }
595+ #endif
487596#ifdef MCUBOOT_UUID_VID
488597 case IMAGE_TLV_UUID_VID :
489598 {
@@ -564,6 +673,13 @@ bootutil_img_validate(struct boot_loader_state *state,
564673 }
565674#endif
566675
676+ #ifdef MCUBOOT_MANIFEST_UPDATES
677+ if (image_index == MCUBOOT_MANIFEST_IMAGE_NUMBER && (!manifest_found || !manifest_valid )) {
678+ BOOT_LOG_ERR ("bootutil_img_validate: slot %d rejected, manifest missing or invalid" , slot );
679+ rc = -1 ;
680+ goto out ;
681+ }
682+ #endif
567683#ifdef MCUBOOT_UUID_VID
568684 if (FIH_NOT_EQ (uuid_vid_valid , FIH_SUCCESS )) {
569685 rc = -1 ;
0 commit comments