@@ -317,6 +317,24 @@ boot_verify_slot_dependency(struct boot_loader_state *state,
317
317
uint8_t swap_type = state -> swap_type [dep -> image_id ];
318
318
dep_slot = BOOT_IS_UPGRADE (swap_type ) ? BOOT_SECONDARY_SLOT
319
319
: BOOT_PRIMARY_SLOT ;
320
+ #elif defined(MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER )
321
+ switch (dep -> slot ) {
322
+ case VERSION_DEP_SLOT_ACTIVE :
323
+ dep_slot = state -> slot_usage [dep -> image_id ].active_slot ;
324
+ break ;
325
+ case VERSION_DEP_SLOT_PRIMARY :
326
+ dep_slot = BOOT_PRIMARY_SLOT ;
327
+ break ;
328
+ case VERSION_DEP_SLOT_SECONDARY :
329
+ dep_slot = BOOT_SECONDARY_SLOT ;
330
+ break ;
331
+ default :
332
+ return -1 ;
333
+ }
334
+
335
+ if (!state -> slot_usage [dep -> image_id ].slot_available [dep_slot ]) {
336
+ return -1 ;
337
+ }
320
338
#else
321
339
dep_slot = state -> slot_usage [dep -> image_id ].active_slot ;
322
340
#endif
@@ -354,7 +372,27 @@ boot_verify_slot_dependency(struct boot_loader_state *state,
354
372
}
355
373
#endif
356
374
357
- return rc ;
375
+ #ifdef MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER
376
+ if (rc == 0 ) {
377
+ switch (dep -> slot ) {
378
+ case VERSION_DEP_SLOT_PRIMARY :
379
+ state -> slot_usage [dep -> image_id ].slot_available [BOOT_PRIMARY_SLOT ] = true;
380
+ state -> slot_usage [dep -> image_id ].slot_available [BOOT_SECONDARY_SLOT ] = false;
381
+ state -> slot_usage [dep -> image_id ].active_slot = BOOT_PRIMARY_SLOT ;
382
+ break ;
383
+ case VERSION_DEP_SLOT_SECONDARY :
384
+ state -> slot_usage [dep -> image_id ].slot_available [BOOT_PRIMARY_SLOT ] = false;
385
+ state -> slot_usage [dep -> image_id ].slot_available [BOOT_SECONDARY_SLOT ] = true;
386
+ state -> slot_usage [dep -> image_id ].active_slot = BOOT_SECONDARY_SLOT ;
387
+ break ;
388
+ case VERSION_DEP_SLOT_ACTIVE :
389
+ default :
390
+ break ;
391
+ }
392
+ }
393
+ #endif /* MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER */
394
+
395
+ return rc ;
358
396
}
359
397
360
398
#if !defined(MCUBOOT_DIRECT_XIP ) && !defined(MCUBOOT_RAM_LOAD )
@@ -499,6 +537,19 @@ boot_verify_slot_dependencies(struct boot_loader_state *state, uint32_t slot)
499
537
goto done ;
500
538
}
501
539
540
+ #ifdef MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER
541
+ /* Validate against possible dependency slot values. */
542
+ switch (dep -> slot ) {
543
+ case VERSION_DEP_SLOT_ACTIVE :
544
+ case VERSION_DEP_SLOT_PRIMARY :
545
+ case VERSION_DEP_SLOT_SECONDARY :
546
+ break ;
547
+ default :
548
+ rc = BOOT_EBADARGS ;
549
+ goto done ;
550
+ }
551
+ #endif /* MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER */
552
+
502
553
/* Verify dependency and modify the swap type if not satisfied. */
503
554
rc = boot_verify_slot_dependency (state , & dep );
504
555
if (rc != 0 ) {
@@ -2674,6 +2725,119 @@ boot_select_or_erase(struct boot_loader_state *state)
2674
2725
}
2675
2726
#endif /* MCUBOOT_DIRECT_XIP && MCUBOOT_DIRECT_XIP_REVERT */
2676
2727
2728
+ #ifdef MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER
2729
+ /**
2730
+ * Tries to load a slot for all the images with validation.
2731
+ *
2732
+ * @param state Boot loader status information.
2733
+ *
2734
+ * @return 0 on success; nonzero on failure.
2735
+ */
2736
+ fih_ret
2737
+ boot_load_and_validate_images (struct boot_loader_state * state )
2738
+ {
2739
+ uint32_t active_slot ;
2740
+ int rc ;
2741
+ fih_ret fih_rc ;
2742
+ uint32_t slot ;
2743
+
2744
+ /* Go over all the images and all slots and validate them */
2745
+ IMAGES_ITER (BOOT_CURR_IMG (state )) {
2746
+ for (slot = 0 ; slot < BOOT_NUM_SLOTS ; slot ++ ) {
2747
+ #if BOOT_IMAGE_NUMBER > 1
2748
+ if (state -> img_mask [BOOT_CURR_IMG (state )]) {
2749
+ continue ;
2750
+ }
2751
+ #endif
2752
+
2753
+ /* Save the number of the active slot. */
2754
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = slot ;
2755
+
2756
+ #ifdef MCUBOOT_DIRECT_XIP
2757
+ rc = boot_rom_address_check (state );
2758
+ if (rc != 0 ) {
2759
+ /* The image is placed in an unsuitable slot. */
2760
+ state -> slot_usage [BOOT_CURR_IMG (state )].slot_available [slot ] = false;
2761
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
2762
+ continue ;
2763
+ }
2764
+
2765
+ #ifdef MCUBOOT_DIRECT_XIP_REVERT
2766
+ rc = boot_select_or_erase (state );
2767
+ if (rc != 0 ) {
2768
+ /* The selected image slot has been erased. */
2769
+ state -> slot_usage [BOOT_CURR_IMG (state )].slot_available [slot ] = false;
2770
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
2771
+ continue ;
2772
+ }
2773
+ #endif /* MCUBOOT_DIRECT_XIP_REVERT */
2774
+ #endif /* MCUBOOT_DIRECT_XIP */
2775
+
2776
+ #ifdef MCUBOOT_RAM_LOAD
2777
+ /* Image is first loaded to RAM and authenticated there in order to
2778
+ * prevent TOCTOU attack during image copy. This could be applied
2779
+ * when loading images from external (untrusted) flash to internal
2780
+ * (trusted) RAM and image is authenticated before copying.
2781
+ */
2782
+ rc = boot_load_image_to_sram (state );
2783
+ if (rc != 0 ) {
2784
+ /* Image cannot be ramloaded. */
2785
+ boot_remove_image_from_flash (state , slot );
2786
+ state -> slot_usage [BOOT_CURR_IMG (state )].slot_available [slot ] = false;
2787
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
2788
+ continue ;
2789
+ }
2790
+ #endif /* MCUBOOT_RAM_LOAD */
2791
+
2792
+ FIH_CALL (boot_validate_slot , fih_rc , state , slot , NULL , 0 );
2793
+ if (FIH_NOT_EQ (fih_rc , FIH_SUCCESS )) {
2794
+ /* Image is invalid. */
2795
+ #ifdef MCUBOOT_RAM_LOAD
2796
+ boot_remove_image_from_sram (state );
2797
+ #endif /* MCUBOOT_RAM_LOAD */
2798
+ state -> slot_usage [BOOT_CURR_IMG (state )].slot_available [slot ] = false;
2799
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
2800
+ continue ;
2801
+ }
2802
+
2803
+ /* Valid image loaded from a slot, go to the next slot. */
2804
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
2805
+ }
2806
+ }
2807
+
2808
+ /* Go over all the images and all slots and validate them */
2809
+ IMAGES_ITER (BOOT_CURR_IMG (state )) {
2810
+ /* All slots tried until a valid image found. Breaking from this loop
2811
+ * means that a valid image found or already loaded. If no slot is
2812
+ * found the function returns with error code. */
2813
+ while (true) {
2814
+ /* Go over all the slots and try to load one */
2815
+ active_slot = state -> slot_usage [BOOT_CURR_IMG (state )].active_slot ;
2816
+ if (active_slot != NO_ACTIVE_SLOT ){
2817
+ /* A slot is already active, go to next image. */
2818
+ break ;
2819
+ }
2820
+
2821
+ active_slot = find_slot_with_highest_version (state );
2822
+ if (active_slot == NO_ACTIVE_SLOT ) {
2823
+ BOOT_LOG_INF ("No slot to load for image %d" ,
2824
+ BOOT_CURR_IMG (state ));
2825
+ FIH_RET (FIH_FAILURE );
2826
+ }
2827
+
2828
+ /* Save the number of the active slot. */
2829
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = active_slot ;
2830
+
2831
+ /* Valid image loaded from a slot, go to the next image. */
2832
+ break ;
2833
+ }
2834
+ }
2835
+
2836
+ FIH_RET (FIH_SUCCESS );
2837
+ }
2838
+
2839
+ #else /* MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER */
2840
+
2677
2841
/**
2678
2842
* Tries to load a slot for all the images with validation.
2679
2843
*
@@ -2771,6 +2935,7 @@ boot_load_and_validate_images(struct boot_loader_state *state)
2771
2935
2772
2936
FIH_RET (FIH_SUCCESS );
2773
2937
}
2938
+ #endif /* MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER */
2774
2939
2775
2940
/**
2776
2941
* Updates the security counter for the current image.
0 commit comments