@@ -471,6 +471,24 @@ boot_verify_slot_dependency(struct boot_loader_state *state,
471
471
uint8_t swap_type = state -> swap_type [dep -> image_id ];
472
472
dep_slot = BOOT_IS_UPGRADE (swap_type ) ? BOOT_SECONDARY_SLOT
473
473
: BOOT_PRIMARY_SLOT ;
474
+ #elif defined(MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER )
475
+ switch (dep -> slot ) {
476
+ case VERSION_DEP_SLOT_ACTIVE :
477
+ dep_slot = state -> slot_usage [dep -> image_id ].active_slot ;
478
+ break ;
479
+ case VERSION_DEP_SLOT_PRIMARY :
480
+ dep_slot = BOOT_PRIMARY_SLOT ;
481
+ break ;
482
+ case VERSION_DEP_SLOT_SECONDARY :
483
+ dep_slot = BOOT_SECONDARY_SLOT ;
484
+ break ;
485
+ default :
486
+ return -1 ;
487
+ }
488
+
489
+ if (!state -> slot_usage [dep -> image_id ].slot_available [dep_slot ]) {
490
+ return -1 ;
491
+ }
474
492
#else
475
493
dep_slot = state -> slot_usage [dep -> image_id ].active_slot ;
476
494
#endif
@@ -508,7 +526,27 @@ boot_verify_slot_dependency(struct boot_loader_state *state,
508
526
}
509
527
#endif
510
528
511
- return rc ;
529
+ #ifdef MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER
530
+ if (rc == 0 ) {
531
+ switch (dep -> slot ) {
532
+ case VERSION_DEP_SLOT_PRIMARY :
533
+ state -> slot_usage [dep -> image_id ].slot_available [BOOT_PRIMARY_SLOT ] = true;
534
+ state -> slot_usage [dep -> image_id ].slot_available [BOOT_SECONDARY_SLOT ] = false;
535
+ state -> slot_usage [dep -> image_id ].active_slot = BOOT_PRIMARY_SLOT ;
536
+ break ;
537
+ case VERSION_DEP_SLOT_SECONDARY :
538
+ state -> slot_usage [dep -> image_id ].slot_available [BOOT_PRIMARY_SLOT ] = false;
539
+ state -> slot_usage [dep -> image_id ].slot_available [BOOT_SECONDARY_SLOT ] = true;
540
+ state -> slot_usage [dep -> image_id ].active_slot = BOOT_SECONDARY_SLOT ;
541
+ break ;
542
+ case VERSION_DEP_SLOT_ACTIVE :
543
+ default :
544
+ break ;
545
+ }
546
+ }
547
+ #endif /* MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER */
548
+
549
+ return rc ;
512
550
}
513
551
514
552
#if !defined(MCUBOOT_DIRECT_XIP ) && !defined(MCUBOOT_RAM_LOAD )
@@ -656,6 +694,19 @@ boot_verify_slot_dependencies(struct boot_loader_state *state, uint32_t slot)
656
694
goto done ;
657
695
}
658
696
697
+ #ifdef MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER
698
+ /* Validate against possible dependency slot values. */
699
+ switch (dep -> slot ) {
700
+ case VERSION_DEP_SLOT_ACTIVE :
701
+ case VERSION_DEP_SLOT_PRIMARY :
702
+ case VERSION_DEP_SLOT_SECONDARY :
703
+ break ;
704
+ default :
705
+ rc = BOOT_EBADARGS ;
706
+ goto done ;
707
+ }
708
+ #endif /* MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER */
709
+
659
710
/* Verify dependency and modify the swap type if not satisfied. */
660
711
rc = boot_verify_slot_dependency (state , & dep );
661
712
if (rc != 0 ) {
@@ -3461,6 +3512,119 @@ boot_select_or_erase(struct boot_loader_state *state)
3461
3512
}
3462
3513
#endif /* MCUBOOT_DIRECT_XIP && MCUBOOT_DIRECT_XIP_REVERT */
3463
3514
3515
+ #ifdef MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER
3516
+ /**
3517
+ * Tries to load a slot for all the images with validation.
3518
+ *
3519
+ * @param state Boot loader status information.
3520
+ *
3521
+ * @return 0 on success; nonzero on failure.
3522
+ */
3523
+ fih_ret
3524
+ boot_load_and_validate_images (struct boot_loader_state * state )
3525
+ {
3526
+ uint32_t active_slot ;
3527
+ int rc ;
3528
+ fih_ret fih_rc ;
3529
+ uint32_t slot ;
3530
+
3531
+ /* Go over all the images and all slots and validate them */
3532
+ IMAGES_ITER (BOOT_CURR_IMG (state )) {
3533
+ for (slot = 0 ; slot < BOOT_NUM_SLOTS ; slot ++ ) {
3534
+ #if BOOT_IMAGE_NUMBER > 1
3535
+ if (state -> img_mask [BOOT_CURR_IMG (state )]) {
3536
+ continue ;
3537
+ }
3538
+ #endif
3539
+
3540
+ /* Save the number of the active slot. */
3541
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = slot ;
3542
+
3543
+ #ifdef MCUBOOT_DIRECT_XIP
3544
+ rc = boot_rom_address_check (state );
3545
+ if (rc != 0 ) {
3546
+ /* The image is placed in an unsuitable slot. */
3547
+ state -> slot_usage [BOOT_CURR_IMG (state )].slot_available [slot ] = false;
3548
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
3549
+ continue ;
3550
+ }
3551
+
3552
+ #ifdef MCUBOOT_DIRECT_XIP_REVERT
3553
+ rc = boot_select_or_erase (state );
3554
+ if (rc != 0 ) {
3555
+ /* The selected image slot has been erased. */
3556
+ state -> slot_usage [BOOT_CURR_IMG (state )].slot_available [slot ] = false;
3557
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
3558
+ continue ;
3559
+ }
3560
+ #endif /* MCUBOOT_DIRECT_XIP_REVERT */
3561
+ #endif /* MCUBOOT_DIRECT_XIP */
3562
+
3563
+ #ifdef MCUBOOT_RAM_LOAD
3564
+ /* Image is first loaded to RAM and authenticated there in order to
3565
+ * prevent TOCTOU attack during image copy. This could be applied
3566
+ * when loading images from external (untrusted) flash to internal
3567
+ * (trusted) RAM and image is authenticated before copying.
3568
+ */
3569
+ rc = boot_load_image_to_sram (state );
3570
+ if (rc != 0 ) {
3571
+ /* Image cannot be ramloaded. */
3572
+ boot_remove_image_from_flash (state , slot );
3573
+ state -> slot_usage [BOOT_CURR_IMG (state )].slot_available [slot ] = false;
3574
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
3575
+ continue ;
3576
+ }
3577
+ #endif /* MCUBOOT_RAM_LOAD */
3578
+
3579
+ FIH_CALL (boot_validate_slot , fih_rc , state , slot , NULL , 0 );
3580
+ if (FIH_NOT_EQ (fih_rc , FIH_SUCCESS )) {
3581
+ /* Image is invalid. */
3582
+ #ifdef MCUBOOT_RAM_LOAD
3583
+ boot_remove_image_from_sram (state );
3584
+ #endif /* MCUBOOT_RAM_LOAD */
3585
+ state -> slot_usage [BOOT_CURR_IMG (state )].slot_available [slot ] = false;
3586
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
3587
+ continue ;
3588
+ }
3589
+
3590
+ /* Valid image loaded from a slot, go to the next slot. */
3591
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = NO_ACTIVE_SLOT ;
3592
+ }
3593
+ }
3594
+
3595
+ /* Go over all the images and all slots and validate them */
3596
+ IMAGES_ITER (BOOT_CURR_IMG (state )) {
3597
+ /* All slots tried until a valid image found. Breaking from this loop
3598
+ * means that a valid image found or already loaded. If no slot is
3599
+ * found the function returns with error code. */
3600
+ while (true) {
3601
+ /* Go over all the slots and try to load one */
3602
+ active_slot = state -> slot_usage [BOOT_CURR_IMG (state )].active_slot ;
3603
+ if (active_slot != NO_ACTIVE_SLOT ){
3604
+ /* A slot is already active, go to next image. */
3605
+ break ;
3606
+ }
3607
+
3608
+ active_slot = find_slot_with_highest_version (state );
3609
+ if (active_slot == NO_ACTIVE_SLOT ) {
3610
+ BOOT_LOG_INF ("No slot to load for image %d" ,
3611
+ BOOT_CURR_IMG (state ));
3612
+ FIH_RET (FIH_FAILURE );
3613
+ }
3614
+
3615
+ /* Save the number of the active slot. */
3616
+ state -> slot_usage [BOOT_CURR_IMG (state )].active_slot = active_slot ;
3617
+
3618
+ /* Valid image loaded from a slot, go to the next image. */
3619
+ break ;
3620
+ }
3621
+ }
3622
+
3623
+ FIH_RET (FIH_SUCCESS );
3624
+ }
3625
+
3626
+ #else /* MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER */
3627
+
3464
3628
/**
3465
3629
* Tries to load a slot for all the images with validation.
3466
3630
*
@@ -3558,6 +3722,7 @@ boot_load_and_validate_images(struct boot_loader_state *state)
3558
3722
3559
3723
FIH_RET (FIH_SUCCESS );
3560
3724
}
3725
+ #endif /* MCUBOOT_VERSION_CMP_USE_SLOT_NUMBER */
3561
3726
3562
3727
/**
3563
3728
* Updates the security counter for the current image.
0 commit comments