blob: b031f13c4844beb6ad3d041d6befea16b239991b [file]
// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0
//! Boot Log structures for OpenTitan.
//!
//! The `BootLog` is populated by early boot stages (ROM and ROM_EXT) to describe
//! the boot process, including slot choices, versions, sizes, and ownership
//! states of the loaded stages. This log is passed to the application via
//! the Retention SRAM (`RetRam.boot_log` field).
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::misc::UnalignedU64;
use crate::tags::{BootSlot, HardenedBool, OwnershipState};
use crate::CheckDigest;
/// Information about the boot flow generated by ROM and ROM_EXT.
///
/// It contains hashes, slot selections, version information, and security levels
/// of the boot components. The entire structure is protected by an integrity digest.
#[derive(Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
#[repr(C)]
pub struct BootLog {
/// A SHA256 integrity digest computed over all subsequent fields in this structure.
pub digest: [u8; 32],
/// A tag identifying this structure. Must be `'BLOG'`.
pub identifier: u32,
/// The hardware/ROM version (typically a Git commit hash prefix).
pub chip_version: UnalignedU64,
/// The boot slot chosen by the ROM to run the ROM Extension (ROM_EXT).
pub rom_ext_slot: BootSlot,
/// ROM_EXT major version.
pub rom_ext_major: u32,
/// ROM_EXT minor version.
pub rom_ext_minor: u32,
/// ROM_EXT size in bytes.
pub rom_ext_size: u32,
/// Anti-replay nonce value used by ROM_EXT.
pub rom_ext_nonce: UnalignedU64,
/// The boot slot chosen by the ROM_EXT to run the owner application (BL0).
pub bl0_slot: BootSlot,
/// The chip's ownership state at boot time.
pub ownership_state: OwnershipState,
/// Cumulative counter of ownership transfers performed on this chip.
pub ownership_transfers: u32,
/// Minimum security version permitted for ROM_EXT images.
pub rom_ext_min_sec_ver: u32,
/// Minimum security version permitted for owner application (BL0) images.
pub bl0_min_sec_ver: u32,
/// The primary BL0 boot slot configured in the chip.
pub primary_bl0_slot: BootSlot,
/// Hardened boolean indicating if the retention RAM was freshly initialized.
pub retention_ram_initialized: HardenedBool,
/// Reserved space for future extensions.
pub reserved: [u32; 8],
}
impl CheckDigest for BootLog {
/// Validates the integrity digest of the `BootLog`.
///
/// The digest is calculated over the structure bytes starting immediately
/// after the `digest` field (byte offset 32).
fn check_digest<F>(&self, f: F) -> bool
where
F: Fn(&[u8]) -> [u8; 32],
{
let digest = f(&self.as_bytes()[32..]);
// OpenTitan digests are stored in reverse byte order
for (a, b) in self.digest.iter().zip(digest.iter().rev()) {
if *a != *b {
return false;
}
}
true
}
/// Computes and sets the integrity digest on the `BootLog`.
fn set_digest<F>(&mut self, f: F)
where
F: Fn(&[u8]) -> [u8; 32],
{
let digest = f(&self.as_bytes()[32..]);
for (a, b) in self.digest.iter_mut().zip(digest.iter().rev()) {
*a = *b;
}
}
}