@@ -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 );
@@ -357,6 +366,69 @@ bootutil_img_validate(struct boot_loader_state *state,
357366 goto out ;
358367 }
359368
369+ #ifdef MCUBOOT_MANIFEST_UPDATES
370+ if (image_index == MCUBOOT_MANIFEST_IMAGE_NUMBER ) {
371+ if (!state -> manifest_valid [slot ]) {
372+ /* Manifest TLV must be processed before any of the image's hash TLV. */
373+ BOOT_LOG_ERR ("bootutil_img_validate: image rejected, manifest not found before "
374+ "image %d hash" , image_index );
375+ rc = -1 ;
376+ goto out ;
377+ }
378+ /* Manifest image does not have hash in the manifest. */
379+ image_hash_valid = 1 ;
380+ break ;
381+ }
382+ #if defined(MCUBOOT_SWAP_USING_SCRATCH ) || defined(MCUBOOT_SWAP_USING_MOVE ) || \
383+ defined(MCUBOOT_SWAP_USING_OFFSET )
384+ state -> matching_manifest [image_index ][slot ] = BOOT_SLOT_NONE ;
385+ /* Try to match with the primary manifest first. */
386+ if (state -> manifest_valid [BOOT_SLOT_PRIMARY ]) {
387+ if (bootutil_verify_manifest_image_hash (& state -> manifest [BOOT_SLOT_PRIMARY ], hash ,
388+ image_index )) {
389+ state -> matching_manifest [image_index ][slot ] = BOOT_SLOT_PRIMARY ;
390+ }
391+ }
392+
393+ /* Try to match with the secondary manifest if not matched with the primary. */
394+ if (state -> matching_manifest [image_index ][slot ] == BOOT_SLOT_NONE &&
395+ state -> manifest_valid [BOOT_SLOT_SECONDARY ]) {
396+ if (bootutil_verify_manifest_image_hash (& state -> manifest [BOOT_SLOT_SECONDARY ], hash ,
397+ image_index )) {
398+ state -> matching_manifest [image_index ][slot ] = BOOT_SLOT_SECONDARY ;
399+ }
400+ }
401+
402+ /* No matching manifest found. */
403+ if (state -> matching_manifest [image_index ][slot ] == BOOT_SLOT_NONE ) {
404+ BOOT_LOG_ERR (
405+ "bootutil_img_validate: image rejected, no valid manifest for image %d slot %d" ,
406+ image_index , slot );
407+ rc = -1 ;
408+ goto out ;
409+ } else {
410+ BOOT_LOG_INF ("bootutil_img_validate: image %d slot %d matches manifest in slot %d" ,
411+ image_index , slot , state -> matching_manifest [image_index ][slot ]);
412+ }
413+ #else /* MCUBOOT_SWAP_USING_SCRATCH || MCUBOOT_SWAP_USING_MOVE || MCUBOOT_SWAP_USING_OFFSET */
414+ /* Manifest image for a given slot must precede any of other images. */
415+ if (!state -> manifest_valid [slot ]) {
416+ /* Manifest TLV must be processed before any of the image's hash TLV. */
417+ BOOT_LOG_ERR ("bootutil_img_validate: image rejected, no valid manifest for slot %d" ,
418+ slot );
419+ rc = -1 ;
420+ goto out ;
421+ }
422+
423+ /* Any image, not described by the manifest is considered as invalid. */
424+ if (!bootutil_verify_manifest_image_hash (& state -> manifest [slot ], hash , image_index )) {
425+ BOOT_LOG_ERR (
426+ "bootutil_img_validate: image rejected, hash does not match manifest contents" );
427+ FIH_SET (fih_rc , FIH_FAILURE );
428+ goto out ;
429+ }
430+ #endif /* MCUBOOT_SWAP_USING_SCRATCH || MCUBOOT_SWAP_USING_MOVE || MCUBOOT_SWAP_USING_OFFSET */
431+ #endif /* MCUBOOT_MANIFEST_UPDATES */
360432 image_hash_valid = 1 ;
361433 break ;
362434 }
@@ -485,6 +557,43 @@ bootutil_img_validate(struct boot_loader_state *state,
485557 break ;
486558 }
487559#endif /* MCUBOOT_HW_ROLLBACK_PROT */
560+ #ifdef MCUBOOT_MANIFEST_UPDATES
561+ case IMAGE_TLV_MANIFEST :
562+ {
563+ /* There can be only one manifest and must be a part of image with specific index. */
564+ if (manifest_found || image_index != MCUBOOT_MANIFEST_IMAGE_NUMBER ||
565+ len != sizeof (struct mcuboot_manifest )) {
566+ BOOT_LOG_ERR (
567+ "bootutil_img_validate: image %d slot %d rejected, unexpected manifest TLV" ,
568+ image_index , slot );
569+ rc = -1 ;
570+ goto out ;
571+ }
572+
573+ manifest_found = true;
574+
575+ rc = LOAD_IMAGE_DATA (hdr , fap , off , & state -> manifest [slot ],
576+ sizeof (struct mcuboot_manifest ));
577+ if (rc ) {
578+ BOOT_LOG_ERR ("bootutil_img_validate: slot %d rejected, unable to load manifest" ,
579+ slot );
580+ goto out ;
581+ }
582+
583+ manifest_valid = bootutil_verify_manifest (& state -> manifest [slot ]);
584+ if (!manifest_valid ) {
585+ BOOT_LOG_ERR ("bootutil_img_validate: slot %d rejected, invalid manifest contents" ,
586+ slot );
587+ rc = -1 ;
588+ goto out ;
589+ }
590+
591+ /* The image's manifest has been successfully verified. */
592+ state -> manifest_valid [slot ] = true;
593+ BOOT_LOG_INF ("bootutil_img_validate: slot %d manifest verified" , slot );
594+ break ;
595+ }
596+ #endif
488597#ifdef MCUBOOT_UUID_VID
489598 case IMAGE_TLV_UUID_VID :
490599 {
@@ -565,6 +674,13 @@ bootutil_img_validate(struct boot_loader_state *state,
565674 }
566675#endif
567676
677+ #ifdef MCUBOOT_MANIFEST_UPDATES
678+ if (image_index == MCUBOOT_MANIFEST_IMAGE_NUMBER && (!manifest_found || !manifest_valid )) {
679+ BOOT_LOG_ERR ("bootutil_img_validate: slot %d rejected, manifest missing or invalid" , slot );
680+ rc = -1 ;
681+ goto out ;
682+ }
683+ #endif
568684#ifdef MCUBOOT_UUID_VID
569685 if (FIH_NOT_EQ (uuid_vid_valid , FIH_SUCCESS )) {
570686 rc = -1 ;
0 commit comments