sim: Add new ram-load test cases
Adds new test cases to various ram-load related logic.
Signed-off-by: Roland Mikhel <roland.mikhel@arm.com>
Change-Id: I3a0ca951b2c720be4e6fe2ed0e5d1830fcfb240c
diff --git a/sim/src/image.rs b/sim/src/image.rs
index 71f2d3c..54e4f31 100644
--- a/sim/src/image.rs
+++ b/sim/src/image.rs
@@ -123,6 +123,19 @@
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 @@
}
/// 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] {
- DepType::NoUpgrade => install_no_image(),
- _ => install_image(&mut flash, &slots[1],
- maximal(46928), &ram, &*dep, false, Some(0))
+
+ 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, img_manipulation, Some(0))
+ };
+ (prim, upgr)
};
OneImage {
slots,
@@ -243,7 +271,7 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
/// 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 @@
}
// Build the TLV itself.
- if bad_sig {
+ if img_manipulation == ImageManipulation::BadSignature {
tlv.corrupt_sig();
}
let mut b_tlv = tlv.make_tlv();
diff --git a/sim/src/lib.rs b/sim/src/lib.rs
index df1919e..fe43e46 100644
--- a/sim/src/lib.rs
+++ b/sim/src/lib.rs
@@ -1,6 +1,6 @@
// 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 @@
image::{
ImagesBuilder,
Images,
+ ImageManipulation,
show_sizes,
},
};
@@ -201,7 +202,7 @@
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);
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index 99c02d9..5541f11 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -112,6 +112,10 @@
/// 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 @@
/// 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 @@
/// 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 @@
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");