[signer] Add image type support
This change adds a new CLI argument for image type (`rom_ext` or
`owner`) and updates relevant `meson.build` files.
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/rom_exts/meson.build b/sw/device/silicon_creator/rom_exts/meson.build
index 5200123..ab12156 100644
--- a/sw/device/silicon_creator/rom_exts/meson.build
+++ b/sw/device/silicon_creator/rom_exts/meson.build
@@ -156,6 +156,7 @@
output: '@BASENAME@.@0@.signed.bin'.format(key_name),
command: [
rom_ext_signer_export.full_path(),
+ 'rom_ext',
'@INPUT@',
key_info['path'],
rom_ext_elf.full_path(),
diff --git a/sw/device/tests/meson.build b/sw/device/tests/meson.build
index 770328d..6d905e6 100644
--- a/sw/device/tests/meson.build
+++ b/sw/device/tests/meson.build
@@ -726,6 +726,7 @@
output: '@BASENAME@.@0@.signed.bin'.format(key_name),
command: [
rom_ext_signer_export.full_path(),
+ 'rom_ext',
'@INPUT@',
key_info['path'],
sw_test_elf.full_path(),
diff --git a/sw/host/rom_ext_image_tools/signer/image/src/image.rs b/sw/host/rom_ext_image_tools/signer/image/src/image.rs
index a30e2fc..24e98d1 100644
--- a/sw/host/rom_ext_image_tools/signer/image/src/image.rs
+++ b/sw/host/rom_ext_image_tools/signer/image/src/image.rs
@@ -45,7 +45,8 @@
}
pub fn signed_bytes(&self) -> Vec<u8> {
- self.bytes().split_off(self.manifest.signature.as_bytes().len())
+ self.bytes()
+ .split_off(self.manifest.signature.as_bytes().len())
}
}
diff --git a/sw/host/rom_ext_image_tools/signer/image/src/manifest.rs b/sw/host/rom_ext_image_tools/signer/image/src/manifest.rs
index cdd2406..af7de91 100644
--- a/sw/host/rom_ext_image_tools/signer/image/src/manifest.rs
+++ b/sw/host/rom_ext_image_tools/signer/image/src/manifest.rs
@@ -25,11 +25,16 @@
// --no-doc-comments --no-layout-tests \
// sw/device/silicon_creator/lib/manifest.h \
// -- -I./ -Isw/device/lib/base/freestanding
+// TODO: Generate some constants as hex if possible, replacing manually for now.
pub const MANIFEST_SIZE: u32 = 896;
-pub const MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL: u32 = 0xA5A5A5A5;
-pub const MANIFEST_LENGTH_FIELD_MIN: u32 = 896;
-pub const MANIFEST_LENGTH_FIELD_MAX: u32 = 65536;
+pub const MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL: u32 = 0xa5a5a5a5;
+pub const MANIFEST_IDENTIFIER_ROM_EXT: u32 = 0x4552544f;
+pub const MANIFEST_IDENTIFIER_OWNER_STAGE: u32 = 0x4f53544f;
+pub const MANIFEST_LENGTH_FIELD_ROM_EXT_MIN: u32 = 896;
+pub const MANIFEST_LENGTH_FIELD_ROM_EXT_MAX: u32 = 0x10000;
+pub const MANIFEST_LENGTH_FIELD_OWNER_STAGE_MIN: u32 = 896;
+pub const MANIFEST_LENGTH_FIELD_OWNER_STAGE_MAX: u32 = 0x70000;
/// Manifest for boot stage images stored in flash.
#[repr(C)]
@@ -88,7 +93,8 @@
Self {
selector_bits: 0,
device_id: LifecycleDeviceId {
- device_id: [MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL; 8usize],
+ device_id: [MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL;
+ 8usize],
},
manuf_state_creator: MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL,
manuf_state_owner: MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL,
diff --git a/sw/host/rom_ext_image_tools/signer/src/main.rs b/sw/host/rom_ext_image_tools/signer/src/main.rs
index af44b04..ef0d57a 100644
--- a/sw/host/rom_ext_image_tools/signer/src/main.rs
+++ b/sw/host/rom_ext_image_tools/signer/src/main.rs
@@ -11,6 +11,7 @@
use std::fs;
use std::mem::size_of;
use std::path::PathBuf;
+use std::str::FromStr;
use mundane::hash::Sha256;
use mundane::public::rsa::RsaPkcs1v15;
@@ -39,8 +40,27 @@
mundane::public::rsa::RsaSignature<B3072, RsaPkcs1v15, Sha256>;
type PrivateKey = mundane::public::rsa::RsaPrivKey<B3072>;
+#[derive(Copy, Clone)]
+enum ImageType {
+ RomExt,
+ OwnerStage,
+}
+
+impl FromStr for ImageType {
+ type Err = anyhow::Error;
+
+ fn from_str(s: &str) -> Result<Self> {
+ match s {
+ "rom_ext" => Ok(ImageType::RomExt),
+ "owner" => Ok(ImageType::OwnerStage),
+ _ => bail!("Unexpected image type: {}", s),
+ }
+ }
+}
+
// TODO: Remove this struct when this functionality is integrated into `opentitantool`.
struct Args {
+ image_type: ImageType,
input_image: PathBuf,
priv_key: PathBuf,
elf_file: PathBuf,
@@ -51,13 +71,16 @@
pub fn new(args: env::ArgsOs) -> Result<Args> {
let args = args.skip(1).collect::<Vec<_>>();
match args.as_slice() {
- [input_image, priv_key, elf_file, output_image] => Ok(Args {
+ [image_type, input_image, priv_key, elf_file, output_image] => Ok(Args {
+ image_type: ImageType::from_str(&image_type.to_string_lossy())?,
input_image: PathBuf::from(input_image),
priv_key: PathBuf::from(priv_key),
elf_file: PathBuf::from(elf_file),
output_image: PathBuf::from(output_image),
}),
- args => bail!("Expected exactly 4 positional arguments: input image, private key, elf file, and output image, got: {}.", args.len()),
+ args => bail!("Expected exactly 5 positional arguments: \
+ image type, input image, private key, elf file, and output image, \
+ got: {}.", args.len()),
}
}
}
@@ -84,6 +107,7 @@
// TODO: This function must use a public key.
fn update_image_manifest(
image: &mut Image,
+ image_type: ImageType,
key: &PrivateKey,
elf: &ElfFile32,
) -> Result<()> {
@@ -93,8 +117,21 @@
.address(),
)?;
+ let (identifier, allowed_lengths) = match image_type {
+ ImageType::RomExt => (
+ manifest::MANIFEST_IDENTIFIER_ROM_EXT,
+ manifest::MANIFEST_LENGTH_FIELD_ROM_EXT_MIN
+ ..=manifest::MANIFEST_LENGTH_FIELD_ROM_EXT_MAX,
+ ),
+ ImageType::OwnerStage => (
+ manifest::MANIFEST_IDENTIFIER_OWNER_STAGE,
+ manifest::MANIFEST_LENGTH_FIELD_OWNER_STAGE_MIN
+ ..=manifest::MANIFEST_LENGTH_FIELD_OWNER_STAGE_MAX,
+ ),
+ };
+
*image.manifest = Manifest {
- identifier: 0x4552544f,
+ identifier,
length: u32::try_from(image.bytes().len())?,
code_start: {
let addr = u32::try_from(
@@ -176,9 +213,7 @@
"`entry_point` is outside the code region."
);
ensure!(
- (manifest::MANIFEST_LENGTH_FIELD_MIN
- ..=manifest::MANIFEST_LENGTH_FIELD_MAX)
- .contains(&image.manifest.length),
+ allowed_lengths.contains(&image.manifest.length),
"`length` is outside the allowed range."
);
@@ -232,7 +267,7 @@
let elf = fs::read(&args.elf_file)?;
let elf = ElfFile32::parse(elf.as_slice())?;
- update_image_manifest(&mut image, &key, &elf)?;
+ update_image_manifest(&mut image, args.image_type, &key, &elf)?;
let sig = calculate_image_signature(&image, &key)?;
update_image_signature(&mut image, sig)?;