@@ -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,12 @@ 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+ const uint8_t * image_hash = NULL ;
256+ #endif
247257#ifdef MCUBOOT_UUID_VID
248258 struct image_uuid img_uuid_vid = {0x00 };
249259 FIH_DECLARE (uuid_vid_valid , FIH_FAILURE );
@@ -356,6 +366,82 @@ bootutil_img_validate(struct boot_loader_state *state,
356366 goto out ;
357367 }
358368
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_INF ("bootutil_img_validate: image rejected, manifest not found before image %d hash" ,
374+ 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 ) || 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+ image_hash = bootutil_get_image_hash (& state -> manifest [BOOT_SLOT_PRIMARY ], image_index );
387+ if (image_hash != NULL ) {
388+ FIH_CALL (boot_fih_memequal , fih_rc , hash , image_hash , sizeof (hash ));
389+ if (FIH_EQ (fih_rc , FIH_SUCCESS )) {
390+ state -> matching_manifest [image_index ][slot ] = BOOT_SLOT_PRIMARY ;
391+ }
392+ }
393+ }
394+
395+ /* Try to match with the secondary manifest if not matched with the primary. */
396+ if (state -> matching_manifest [image_index ][slot ] == BOOT_SLOT_NONE &&
397+ state -> manifest_valid [BOOT_SLOT_SECONDARY ]) {
398+ image_hash = bootutil_get_image_hash (& state -> manifest [BOOT_SLOT_SECONDARY ], image_index );
399+ if (image_hash != NULL ) {
400+ FIH_CALL (boot_fih_memequal , fih_rc , hash , image_hash , sizeof (hash ));
401+ if (FIH_EQ (fih_rc , FIH_SUCCESS )) {
402+ state -> matching_manifest [image_index ][slot ] = BOOT_SLOT_SECONDARY ;
403+ }
404+ }
405+ }
406+
407+ /* No matching manifest found. */
408+ if (state -> matching_manifest [image_index ][slot ] == BOOT_SLOT_NONE ) {
409+ BOOT_LOG_INF ("bootutil_img_validate: image rejected, no valid manifest for image %d slot %d" ,
410+ image_index , slot );
411+ rc = -1 ;
412+ goto out ;
413+ } else {
414+ BOOT_LOG_INF ("bootutil_img_validate: image %d slot %d matches manifest in slot %d" ,
415+ image_index , slot , state -> matching_manifest [image_index ][slot ]);
416+ }
417+ #else /* MCUBOOT_SWAP_USING_SCRATCH || MCUBOOT_SWAP_USING_MOVE || MCUBOOT_SWAP_USING_OFFSET */
418+ /* Manifest image for a given slot must precede any of other images. */
419+ if (!state -> manifest_valid [slot ]) {
420+ /* Manifest TLV must be processed before any of the image's hash TLV. */
421+ BOOT_LOG_INF ("bootutil_img_validate: image rejected, no valid manifest for slot %d" ,
422+ slot );
423+ rc = -1 ;
424+ goto out ;
425+ }
426+
427+ /* Any image, not described by the manifest is considered as invalid. */
428+ image_hash = bootutil_get_image_hash (& state -> manifest [slot ], image_index );
429+ if (image_hash == NULL ) {
430+ /* Manifest TLV must be processed before any of the image's hash TLV. */
431+ BOOT_LOG_INF ("bootutil_img_validate: image rejected, no valid manifest for image %d slot %d" ,
432+ image_index , slot );
433+ rc = -1 ;
434+ goto out ;
435+ }
436+
437+ FIH_CALL (boot_fih_memequal , fih_rc , hash , image_hash , sizeof (hash ));
438+ if (FIH_NOT_EQ (fih_rc , FIH_SUCCESS )) {
439+ BOOT_LOG_INF ("bootutil_img_validate: image rejected, hash does not match manifest contents" );
440+ FIH_SET (fih_rc , FIH_FAILURE );
441+ goto out ;
442+ }
443+ #endif /* MCUBOOT_SWAP_USING_SCRATCH || MCUBOOT_SWAP_USING_MOVE || MCUBOOT_SWAP_USING_OFFSET */
444+ #endif /* MCUBOOT_MANIFEST_UPDATES */
359445 image_hash_valid = 1 ;
360446 break ;
361447 }
@@ -484,6 +570,39 @@ bootutil_img_validate(struct boot_loader_state *state,
484570 break ;
485571 }
486572#endif /* MCUBOOT_HW_ROLLBACK_PROT */
573+ #ifdef MCUBOOT_MANIFEST_UPDATES
574+ case IMAGE_TLV_MANIFEST :
575+ {
576+ /* There can be only one manifest and must be a part of image with specific index. */
577+ if (manifest_found || image_index != MCUBOOT_MANIFEST_IMAGE_NUMBER ||
578+ len != sizeof (struct mcuboot_manifest )) {
579+ BOOT_LOG_INF ("bootutil_img_validate: image %d slot %d rejected, unexpected manifest TLV" ,
580+ image_index , slot );
581+ rc = -1 ;
582+ goto out ;
583+ }
584+
585+ manifest_found = true;
586+
587+ rc = LOAD_IMAGE_DATA (hdr , fap , off , & state -> manifest [slot ], sizeof (struct mcuboot_manifest ));
588+ if (rc ) {
589+ BOOT_LOG_INF ("bootutil_img_validate: slot %d rejected, unable to load manifest" , slot );
590+ goto out ;
591+ }
592+
593+ manifest_valid = bootutil_verify_manifest (& state -> manifest [slot ]);
594+ if (!manifest_valid ) {
595+ BOOT_LOG_INF ("bootutil_img_validate: slot %d rejected, invalid manifest contents" , slot );
596+ rc = -1 ;
597+ goto out ;
598+ }
599+
600+ /* The image's manifest has been successfully verified. */
601+ state -> manifest_valid [slot ] = true;
602+ BOOT_LOG_INF ("bootutil_img_validate: slot %d manifest verified" , slot );
603+ break ;
604+ }
605+ #endif
487606#ifdef MCUBOOT_UUID_VID
488607 case IMAGE_TLV_UUID_VID :
489608 {
@@ -564,6 +683,13 @@ bootutil_img_validate(struct boot_loader_state *state,
564683 }
565684#endif
566685
686+ #ifdef MCUBOOT_MANIFEST_UPDATES
687+ if (image_index == MCUBOOT_MANIFEST_IMAGE_NUMBER && (!manifest_found || !manifest_valid )) {
688+ BOOT_LOG_INF ("bootutil_img_validate: slot %d rejected, manifest missing or invalid" , slot );
689+ rc = -1 ;
690+ goto out ;
691+ }
692+ #endif
567693#ifdef MCUBOOT_UUID_VID
568694 if (FIH_NOT_EQ (uuid_vid_valid , FIH_SUCCESS )) {
569695 rc = -1 ;
0 commit comments