Commit 6945bb6c authored by Roland Mikhel's avatar Roland Mikhel Committed by Dávid Vincze
Browse files

sim: Add new ram-load test cases



Adds new test cases to various ram-load related logic.

Signed-off-by: default avatarRoland Mikhel <roland.mikhel@arm.com>
Change-Id: I3a0ca951b2c720be4e6fe2ed0e5d1830fcfb240c
parent 820e9cce
Loading
Loading
Loading
Loading
+80 −22
Original line number Diff line number Diff line
@@ -123,6 +123,19 @@ struct SlotPlace {
    size: u32,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ImageManipulation {
    None,
    BadSignature,
    WrongOffset,
    IgnoreRamLoadFlag,
    /// True to use same address,
    /// false to overlap by 1 byte
    OverlapImages(bool),
    CorruptHigherVersionImage,
}


impl ImagesBuilder {
    /// Construct a new image builder for the given device.  Returns
    /// Some(builder) if is possible to test this configuration, or None if
@@ -210,22 +223,37 @@ impl ImagesBuilder {
    }

    /// Construct an `Images` that doesn't expect an upgrade to happen.
    pub fn make_no_upgrade_image(self, deps: &DepTest) -> Images {
    pub fn make_no_upgrade_image(self, deps: &DepTest, img_manipulation: ImageManipulation) -> Images {
        let num_images = self.num_images();
        let mut flash = self.flash;
        let ram = self.ram.clone();  // TODO: This is wasteful.
        let ram = self.ram.clone();  // TODO: Avoid this clone.
        let mut higher_version_corrupted = false;
        let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
            let dep: Box<dyn Depender> = if num_images > 1 {
                Box::new(PairDep::new(num_images, image_num, deps))
            } else {
                Box::new(BoringDep::new(image_num, deps))
            };
            let primaries = install_image(&mut flash, &slots[0],
                maximal(42784), &ram, &*dep, false, Some(0));
            let upgrades = match deps.depends[image_num] {

            let (primaries,upgrades) =  if img_manipulation == ImageManipulation::CorruptHigherVersionImage && !higher_version_corrupted {
                higher_version_corrupted = true;
               let prim =  install_image(&mut flash, &slots[0],
                    maximal(42784), &ram, &*dep, ImageManipulation::None, Some(0));
                let upgr   = match deps.depends[image_num] {
                    DepType::NoUpgrade => install_no_image(),
                    _ => install_image(&mut flash, &slots[1],
                        maximal(46928), &ram, &*dep, ImageManipulation::BadSignature, Some(0))
                };
                (prim, upgr)
            } else {
                let prim = install_image(&mut flash, &slots[0],
                    maximal(42784), &ram, &*dep, img_manipulation, Some(0));
                let upgr = match deps.depends[image_num] {
                        DepType::NoUpgrade => install_no_image(),
                        _ => install_image(&mut flash, &slots[1],
                    maximal(46928), &ram, &*dep, false, Some(0))
                            maximal(46928), &ram, &*dep, img_manipulation, Some(0))
                    };
                (prim, upgr)
            };
            OneImage {
                slots,
@@ -243,7 +271,7 @@ impl ImagesBuilder {
    }

    pub fn make_image(self, deps: &DepTest, permanent: bool) -> Images {
        let mut images = self.make_no_upgrade_image(deps);
        let mut images = self.make_no_upgrade_image(deps, ImageManipulation::None);
        for image in &images.images {
            mark_upgrade(&mut images.flash, &image.slots[1]);
        }
@@ -274,9 +302,9 @@ impl ImagesBuilder {
        let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
            let dep = BoringDep::new(image_num, &NO_DEPS);
            let primaries = install_image(&mut bad_flash, &slots[0],
                maximal(32784), &ram, &dep, false, Some(0));
                maximal(32784), &ram, &dep, ImageManipulation::None, Some(0));
            let upgrades = install_image(&mut bad_flash, &slots[1],
                maximal(41928), &ram, &dep, true, Some(0));
                maximal(41928), &ram, &dep, ImageManipulation::BadSignature, Some(0));
            OneImage {
                slots,
                primaries,
@@ -297,9 +325,9 @@ impl ImagesBuilder {
        let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
            let dep = BoringDep::new(image_num, &NO_DEPS);
            let primaries = install_image(&mut bad_flash, &slots[0],
                maximal(32784), &ram, &dep, false, Some(0));
                maximal(32784), &ram, &dep, ImageManipulation::None, Some(0));
            let upgrades = install_image(&mut bad_flash, &slots[1],
                ImageSize::Oversized, &ram, &dep, false, Some(0));
                ImageSize::Oversized, &ram, &dep, ImageManipulation::None, Some(0));
            OneImage {
                slots,
                primaries,
@@ -320,7 +348,7 @@ impl ImagesBuilder {
        let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
            let dep = BoringDep::new(image_num, &NO_DEPS);
            let primaries = install_image(&mut flash, &slots[0],
                maximal(32784), &ram, &dep, false, Some(0));
                maximal(32784), &ram, &dep,ImageManipulation::None, Some(0));
            let upgrades = install_no_image();
            OneImage {
                slots,
@@ -343,7 +371,7 @@ impl ImagesBuilder {
            let dep = BoringDep::new(image_num, &NO_DEPS);
            let primaries = install_no_image();
            let upgrades = install_image(&mut flash, &slots[1],
                maximal(32784), &ram, &dep, false, Some(0));
                maximal(32784), &ram, &dep, ImageManipulation::None, Some(0));
            OneImage {
                slots,
                primaries,
@@ -365,7 +393,7 @@ impl ImagesBuilder {
            let dep = BoringDep::new(image_num, &NO_DEPS);
            let primaries = install_no_image();
            let upgrades = install_image(&mut flash, &slots[1],
                ImageSize::Oversized, &ram, &dep, false, Some(0));
                ImageSize::Oversized, &ram, &dep, ImageManipulation::None, Some(0));
            OneImage {
                slots,
                primaries,
@@ -387,9 +415,9 @@ impl ImagesBuilder {
        let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
            let dep = BoringDep::new(image_num, &NO_DEPS);
            let primaries = install_image(&mut flash, &slots[0],
                maximal(32784), &ram, &dep, false, security_cnt);
                maximal(32784), &ram, &dep,  ImageManipulation::None, security_cnt);
            let upgrades = install_image(&mut flash, &slots[1],
                maximal(41928), &ram, &dep, false, security_cnt.map(|v| v + 1));
                maximal(41928), &ram, &dep, ImageManipulation::None, security_cnt.map(|v| v + 1));
            OneImage {
                slots,
                primaries,
@@ -1318,6 +1346,28 @@ impl Images {
        false
    }

    pub fn run_ram_load_boot_with_result(&self, expected_result: bool) -> bool {
        if !Caps::RamLoad.present() {
            return false;
        }
        // Clone the flash so we can tell if unchanged.
        let mut flash = self.flash.clone();

        // Create RAM config.
        let ram = RamBlock::new(self.ram.total - RAM_LOAD_ADDR, RAM_LOAD_ADDR);

        // Run the bootloader, and verify that it couldn't run to completion.
        let result = ram.invoke(|| c::boot_go(&mut flash, &self.areadesc, None,
            None, true));

        if result.success() != expected_result {
            error!("RAM load boot result was not of the expected value! (was: {}, expected: {})", result.success(), expected_result);
            return true;
        }

        false
    }

    /// Adds a new flash area that fails statistically
    fn mark_bad_status_with_rate(&self, flash: &mut SimMultiFlash, slot: usize,
                                 rate: f32) {
@@ -1699,26 +1749,34 @@ fn image_largest_trailer(dev: &dyn Flash) -> usize {
/// fields used by the given code.  Returns a copy of the image that was written.
fn install_image(flash: &mut SimMultiFlash, slot: &SlotInfo, len: ImageSize,
                 ram: &RamData,
                 deps: &dyn Depender, bad_sig: bool, security_counter:Option<u32>) -> ImageData {
                 deps: &dyn Depender, img_manipulation: ImageManipulation, security_counter:Option<u32>) -> ImageData {
    let offset = slot.base_off;
    let slot_len = slot.len;
    let dev_id = slot.dev_id;
    let dev = flash.get_mut(&dev_id).unwrap();

    let mut tlv: Box<dyn ManifestGen> = Box::new(make_tlv());
    if img_manipulation == ImageManipulation::IgnoreRamLoadFlag {
        tlv.set_ignore_ram_load_flag();
    }

    tlv.set_security_counter(security_counter);


    // Add the dependencies early to the tlv.
    for dep in deps.my_deps(offset, slot.index) {
        tlv.add_dependency(deps.other_id(), &dep);
    }

    const HDR_SIZE: usize = 32;

    let place = ram.lookup(&slot);
    let load_addr = if Caps::RamLoad.present() {
        place.offset
        match img_manipulation {
            ImageManipulation::WrongOffset => u32::MAX,
            ImageManipulation::OverlapImages(true) => RAM_LOAD_ADDR,
            ImageManipulation::OverlapImages(false) => place.offset - 1,
            _ => place.offset
        }
    } else {
        0
    };
@@ -1803,7 +1861,7 @@ fn install_image(flash: &mut SimMultiFlash, slot: &SlotInfo, len: ImageSize,
    }

    // Build the TLV itself.
    if bad_sig {
    if img_manipulation == ImageManipulation::BadSignature  {
        tlv.corrupt_sig();
    }
    let mut b_tlv = tlv.make_tlv();
+3 −2
Original line number Diff line number Diff line
// Copyright (c) 2017-2019 Linaro LTD
// Copyright (c) 2017-2019 JUUL Labs
// Copyright (c) 2019 Arm Limited
// Copyright (c) 2019-2023 Arm Limited
//
// SPDX-License-Identifier: Apache-2.0

@@ -30,6 +30,7 @@ pub use crate::{
    image::{
        ImagesBuilder,
        Images,
        ImageManipulation,
        show_sizes,
    },
};
@@ -201,7 +202,7 @@ impl RunStatus {

        failed |= bad_secondary_slot_image.run_signfail_upgrade();

        let images = run.clone().make_no_upgrade_image(&NO_DEPS);
        let images = run.clone().make_no_upgrade_image(&NO_DEPS, ImageManipulation::None);
        failed |= images.run_norevert_newimage();

        let images = run.make_image(&NO_DEPS, true);
+11 −1
Original line number Diff line number Diff line
@@ -112,6 +112,10 @@ pub trait ManifestGen {

    /// Set the security counter to the specified value.
    fn set_security_counter(&mut self, security_cnt: Option<u32>);

    /// Sets the ignore_ram_load_flag so that can be validated when it is missing,
    /// it will not load successfully.
    fn set_ignore_ram_load_flag(&mut self);
}

#[derive(Debug, Default)]
@@ -124,6 +128,8 @@ pub struct TlvGen {
    /// Should this signature be corrupted.
    gen_corrupted: bool,
    security_cnt: Option<u32>,
    /// Ignore RAM_LOAD flag
    ignore_ram_load_flag: bool,
}

#[derive(Debug)]
@@ -318,7 +324,7 @@ impl ManifestGen for TlvGen {
    /// Retrieve the header flags for this configuration.  This can be called at any time.
    fn get_flags(&self) -> u32 {
        // For the RamLoad case, add in the flag for this feature.
        if Caps::RamLoad.present() {
        if Caps::RamLoad.present() && !self.ignore_ram_load_flag {
            self.flags | (TlvFlags::RAM_LOAD as u32)
        } else {
            self.flags
@@ -793,6 +799,10 @@ impl ManifestGen for TlvGen {
    fn set_security_counter(&mut self, security_cnt: Option<u32>) {
        self.security_cnt = security_cnt;
    }

    fn set_ignore_ram_load_flag(&mut self) {
        self.ignore_ram_load_flag = true;
    }
}

include!("rsa_pub_key-rs.txt");
+15 −5
Original line number Diff line number Diff line
// Copyright (c) 2017-2021 Linaro LTD
// Copyright (c) 2017-2019 JUUL Labs
// Copyright (c) 2023 Arm Limited
// Copyright (c) 2021-2023 Arm Limited
//
// SPDX-License-Identifier: Apache-2.0

@@ -15,6 +15,7 @@ use bootsim::{
    NO_DEPS,
    REV_DEPS,
    testlog,
    ImageManipulation
};
use std::{
    env,
@@ -51,7 +52,7 @@ sim_test!(bad_secondary_slot, make_bad_secondary_slot_image(), run_signfail_upgr
sim_test!(secondary_trailer_leftover, make_erased_secondary_image(), run_secondary_leftover_trailer());
sim_test!(bootstrap, make_bootstrap_image(), run_bootstrap());
sim_test!(oversized_bootstrap, make_oversized_bootstrap_image(), run_oversized_bootstrap());
sim_test!(norevert_newimage, make_no_upgrade_image(&NO_DEPS), run_norevert_newimage());
sim_test!(norevert_newimage, make_no_upgrade_image(&NO_DEPS, ImageManipulation::None), run_norevert_newimage());
sim_test!(basic_revert, make_image(&NO_DEPS, true), run_basic_revert());
sim_test!(revert_with_fails, make_image(&NO_DEPS, false), run_revert_with_fails());
sim_test!(perm_with_fails, make_image(&NO_DEPS, true), run_perm_with_fails());
@@ -65,11 +66,20 @@ sim_test!(status_write_fails_complete, make_image(&NO_DEPS, true), run_with_stat
sim_test!(status_write_fails_with_reset, make_image(&NO_DEPS, true), run_with_status_fails_with_reset());
sim_test!(downgrade_prevention, make_image(&REV_DEPS, true), run_nodowngrade());

sim_test!(direct_xip_first, make_no_upgrade_image(&NO_DEPS), run_direct_xip());
sim_test!(ram_load_first, make_no_upgrade_image(&NO_DEPS), run_ram_load());
sim_test!(ram_load_split, make_no_upgrade_image(&NO_DEPS), run_split_ram_load());
sim_test!(direct_xip_first, make_no_upgrade_image(&NO_DEPS, ImageManipulation::None), run_direct_xip());
sim_test!(ram_load_first, make_no_upgrade_image(&NO_DEPS, ImageManipulation::None), run_ram_load());
sim_test!(ram_load_split, make_no_upgrade_image(&NO_DEPS, ImageManipulation::None), run_split_ram_load());
sim_test!(hw_prot_failed_security_cnt_check, make_image_with_security_counter(Some(0)), run_hw_rollback_prot());
sim_test!(hw_prot_missing_security_cnt, make_image_with_security_counter(None), run_hw_rollback_prot());
sim_test!(ram_load_out_of_bounds, make_no_upgrade_image(&NO_DEPS, ImageManipulation::WrongOffset), run_ram_load_boot_with_result(false));
sim_test!(ram_load_missing_header_flag, make_no_upgrade_image(&NO_DEPS, ImageManipulation::IgnoreRamLoadFlag), run_ram_load_boot_with_result(false));
sim_test!(ram_load_failed_validation, make_no_upgrade_image(&NO_DEPS, ImageManipulation::BadSignature), run_ram_load_boot_with_result(false));
sim_test!(ram_load_corrupt_higher_version_image, make_no_upgrade_image(&NO_DEPS, ImageManipulation::CorruptHigherVersionImage), run_ram_load_boot_with_result(true));

#[cfg(feature = "multiimage")]
sim_test!(ram_load_overlapping_images_same_base, make_no_upgrade_image(&NO_DEPS, ImageManipulation::OverlapImages(true)), run_ram_load_boot_with_result(false));
#[cfg(feature = "multiimage")]
sim_test!(ram_load_overlapping_images_offset, make_no_upgrade_image(&NO_DEPS, ImageManipulation::OverlapImages(false)), run_ram_load_boot_with_result(false));

// Test various combinations of incorrect dependencies.
test_shell!(dependency_combos, r, {