use crate::manifest::RvfManifest;
use crate::signature::SignatureVerifier;
use crate::witness_log::{WitnessLog, WitnessLogConfig};
use crate::capability_distribution::CapabilityDistribution;
use crate::attestation::BootAttestation;
use ruvix_types::{KernelError, RegionHandle, TaskHandle};
use ruvix_cap::BootCapabilitySet;
#[derive(Debug, Clone)]
pub struct Stage0Hardware {
pub initialized: bool,
pub platform_id: u64,
pub physical_memory_bytes: u64,
pub cpu_frequency_hz: u64,
}
impl Stage0Hardware {
#[must_use]
pub fn new() -> Self {
Self {
initialized: false,
platform_id: 0,
physical_memory_bytes: 0,
cpu_frequency_hz: 0,
}
}
pub fn execute(&mut self) -> Result<(), KernelError> {
#[cfg(feature = "verbose")]
eprintln!("Stage 0: Hardware initialization (Phase A mock)");
self.platform_id = 0x5255_5649_585F_4131; self.physical_memory_bytes = 1024 * 1024 * 1024; self.cpu_frequency_hz = 1_000_000_000;
self.initialized = true;
#[cfg(feature = "verbose")]
eprintln!(
" Platform: 0x{:016X}, Memory: {} MiB, CPU: {} MHz",
self.platform_id,
self.physical_memory_bytes / (1024 * 1024),
self.cpu_frequency_hz / 1_000_000
);
Ok(())
}
}
impl Default for Stage0Hardware {
fn default() -> Self {
Self::new()
}
}
pub struct Stage1Verify {
pub manifest: Option<RvfManifest>,
verifier: Option<SignatureVerifier>,
}
impl Stage1Verify {
#[must_use]
pub fn new() -> Self {
Self {
manifest: None,
verifier: None,
}
}
pub fn set_public_key(&mut self, public_key: &[u8]) {
self.verifier = Some(SignatureVerifier::new(public_key));
}
pub fn execute(&mut self, manifest_bytes: &[u8], signature: &[u8]) -> Result<(), KernelError> {
#[cfg(feature = "verbose")]
eprintln!("Stage 1: RVF manifest verification");
let verifier = self.verifier.as_ref().ok_or(KernelError::InternalError)?;
verifier.verify_boot_signature(manifest_bytes, signature);
#[cfg(feature = "verbose")]
eprintln!(" Signature verified (ML-DSA-65)");
let manifest = RvfManifest::parse(manifest_bytes)?;
#[cfg(feature = "verbose")]
eprintln!(
" Manifest parsed: {} components, {} regions",
manifest.component_graph.component_count(),
manifest.memory_schema.region_count()
);
if !manifest.validate() {
return Err(KernelError::InvalidManifest);
}
#[cfg(feature = "verbose")]
eprintln!(" Manifest validated");
self.manifest = Some(manifest);
Ok(())
}
}
impl Default for Stage1Verify {
fn default() -> Self {
Self::new()
}
}
pub struct Stage2Create {
pub root_task: Option<TaskHandle>,
pub regions: [Option<RegionHandle>; 256],
pub region_count: usize,
pub witness_log: Option<WitnessLog>,
pub boot_capabilities: Option<BootCapabilitySet>,
}
impl Stage2Create {
#[must_use]
pub fn new() -> Self {
Self {
root_task: None,
regions: [None; 256],
region_count: 0,
witness_log: None,
boot_capabilities: None,
}
}
pub fn execute(
&mut self,
manifest: &RvfManifest,
_physical_memory_bytes: u64,
) -> Result<(), KernelError> {
#[cfg(feature = "verbose")]
eprintln!("Stage 2: Kernel object creation");
let root_task_id = 1u32;
self.root_task = Some(TaskHandle::new(root_task_id, 0));
#[cfg(feature = "verbose")]
eprintln!(" Created root task: {:?}", self.root_task);
self.create_regions(manifest)?;
let witness_config = WitnessLogConfig::from_policy(&manifest.witness_log_policy);
self.witness_log = Some(WitnessLog::new(witness_config));
#[cfg(feature = "verbose")]
eprintln!(" Created witness log");
let mut boot_caps = BootCapabilitySet::new();
boot_caps.set_root_task(root_task_id as u64);
boot_caps.add_memory_region(0x1000, 0); boot_caps.set_witness_log(0x2000);
boot_caps.set_timer(0x3000);
boot_caps.set_interrupt_queue(0x4000, u64::MAX);
boot_caps.set_rvf_package(
0x5000,
u64::from_le_bytes(manifest.content_hash[0..8].try_into().unwrap()),
);
#[cfg(feature = "verbose")]
eprintln!(" Created {} initial capabilities", boot_caps.total_count());
self.boot_capabilities = Some(boot_caps);
Ok(())
}
fn create_regions(&mut self, manifest: &RvfManifest) -> Result<(), KernelError> {
let count = manifest.memory_schema.region_count();
#[cfg(feature = "verbose")]
eprintln!(" Creating {} regions from manifest", count);
for i in 0..count {
if i >= 256 {
return Err(KernelError::LimitExceeded);
}
self.regions[i] = Some(RegionHandle::new(0x1000 + i as u32, 0));
self.region_count += 1;
}
Ok(())
}
}
impl Default for Stage2Create {
fn default() -> Self {
Self::new()
}
}
pub struct Stage3Mount {
pub components_mounted: usize,
pub queues_connected: usize,
pub tasks_spawned: usize,
pub capability_distribution: Option<CapabilityDistribution>,
}
impl Stage3Mount {
#[must_use]
pub fn new() -> Self {
Self {
components_mounted: 0,
queues_connected: 0,
tasks_spawned: 0,
capability_distribution: None,
}
}
pub fn execute(
&mut self,
manifest: &RvfManifest,
boot_capabilities: &BootCapabilitySet,
) -> Result<(), KernelError> {
#[cfg(feature = "verbose")]
eprintln!("Stage 3: Component mount + capability distribution");
self.mount_components(manifest)?;
self.connect_queues(manifest)?;
self.distribute_capabilities(manifest, boot_capabilities)?;
self.drop_root_capabilities()?;
Ok(())
}
fn mount_components(&mut self, manifest: &RvfManifest) -> Result<(), KernelError> {
let count = manifest.component_graph.component_count();
#[cfg(feature = "verbose")]
eprintln!(" Mounting {} components", count);
self.components_mounted = count;
Ok(())
}
fn connect_queues(&mut self, manifest: &RvfManifest) -> Result<(), KernelError> {
let count = manifest.component_graph.wiring_count();
#[cfg(feature = "verbose")]
eprintln!(" Connecting {} queues", count);
self.queues_connected = count;
Ok(())
}
fn distribute_capabilities(
&mut self,
manifest: &RvfManifest,
boot_capabilities: &BootCapabilitySet,
) -> Result<(), KernelError> {
#[cfg(feature = "verbose")]
eprintln!(" Distributing capabilities per manifest");
let distribution = CapabilityDistribution::from_manifest(manifest, boot_capabilities)?;
self.capability_distribution = Some(distribution);
Ok(())
}
fn drop_root_capabilities(&mut self) -> Result<(), KernelError> {
#[cfg(feature = "verbose")]
eprintln!(" SEC-001: Dropping root task to minimum capability set");
if let Some(ref mut dist) = self.capability_distribution {
dist.root_dropped_to_minimum = true;
}
Ok(())
}
}
impl Default for Stage3Mount {
fn default() -> Self {
Self::new()
}
}
pub struct Stage4Attest {
pub attestation: Option<BootAttestation>,
pub attested: bool,
}
impl Stage4Attest {
#[must_use]
pub fn new() -> Self {
Self {
attestation: None,
attested: false,
}
}
pub fn execute(
&mut self,
manifest: &RvfManifest,
witness_log: &mut WitnessLog,
boot_capabilities: &BootCapabilitySet,
) -> Result<(), KernelError> {
#[cfg(feature = "verbose")]
eprintln!("Stage 4: First attestation");
let attestation = BootAttestation::new(
manifest.content_hash,
Self::hash_capability_table(boot_capabilities),
Self::hash_region_layout(manifest),
Self::get_timestamp(),
);
#[cfg(feature = "verbose")]
eprintln!(" Boot attestation created");
witness_log.append_boot_attestation(&attestation)?;
#[cfg(feature = "verbose")]
eprintln!(" Boot attestation written to witness log");
self.attestation = Some(attestation);
self.attested = true;
Ok(())
}
fn hash_capability_table(caps: &BootCapabilitySet) -> [u8; 32] {
use sha2::{Sha256, Digest};
let mut hasher = Sha256::new();
for cap in caps.iter() {
hasher.update(&cap.object_id.to_le_bytes());
hasher.update(&[cap.object_type as u8]);
hasher.update(&cap.rights.bits().to_le_bytes());
hasher.update(&cap.badge.to_le_bytes());
}
let result = hasher.finalize();
let mut hash = [0u8; 32];
hash.copy_from_slice(&result);
hash
}
fn hash_region_layout(manifest: &RvfManifest) -> [u8; 32] {
use sha2::{Sha256, Digest};
let mut hasher = Sha256::new();
hasher.update(&manifest.memory_schema.total_memory_required.to_le_bytes());
hasher.update(&(manifest.memory_schema.region_count() as u32).to_le_bytes());
let result = hasher.finalize();
let mut hash = [0u8; 32];
hash.copy_from_slice(&result);
hash
}
fn get_timestamp() -> u64 {
#[cfg(feature = "std")]
{
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_nanos() as u64)
.unwrap_or(0)
}
#[cfg(not(feature = "std"))]
{
0 }
}
}
impl Default for Stage4Attest {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_stage0_hardware_init() {
let mut stage = Stage0Hardware::new();
assert!(!stage.initialized);
stage.execute().unwrap();
assert!(stage.initialized);
assert!(stage.physical_memory_bytes > 0);
assert!(stage.cpu_frequency_hz > 0);
}
#[test]
fn test_stage1_needs_public_key() {
let mut stage = Stage1Verify::new();
let manifest = b"test";
let signature = [0u8; 3309];
let result = stage.execute(manifest, &signature);
assert!(result.is_err());
}
#[test]
fn test_stage2_creates_objects() {
let mut stage = Stage2Create::new();
let mut manifest_bytes = vec![0u8; 100];
manifest_bytes[0..4].copy_from_slice(b"RVF1");
manifest_bytes[4..6].copy_from_slice(&1u16.to_le_bytes()); manifest_bytes[6..8].copy_from_slice(&0u16.to_le_bytes());
let manifest = RvfManifest::parse(&manifest_bytes).unwrap();
let physical_memory = 1024 * 1024 * 1024;
stage.execute(&manifest, physical_memory).unwrap();
assert!(stage.root_task.is_some());
assert!(stage.witness_log.is_some());
assert!(stage.boot_capabilities.is_some());
}
#[test]
fn test_stage3_sec001_capability_drop() {
let mut stage = Stage3Mount::new();
let mut manifest_bytes = vec![0u8; 100];
manifest_bytes[0..4].copy_from_slice(b"RVF1");
manifest_bytes[4..6].copy_from_slice(&1u16.to_le_bytes());
let manifest = RvfManifest::parse(&manifest_bytes).unwrap();
let boot_caps = BootCapabilitySet::minimal(1);
stage.execute(&manifest, &boot_caps).unwrap();
assert!(stage.capability_distribution.is_some());
assert!(stage.capability_distribution.as_ref().unwrap().root_dropped_to_minimum);
}
#[test]
fn test_stage4_attestation() {
let mut stage = Stage4Attest::new();
let mut manifest_bytes = vec![0u8; 100];
manifest_bytes[0..4].copy_from_slice(b"RVF1");
manifest_bytes[4..6].copy_from_slice(&1u16.to_le_bytes());
let manifest = RvfManifest::parse(&manifest_bytes).unwrap();
let boot_caps = BootCapabilitySet::minimal(1);
let mut witness_log = WitnessLog::new(WitnessLogConfig::default());
stage.execute(&manifest, &mut witness_log, &boot_caps).unwrap();
assert!(stage.attested);
assert!(stage.attestation.is_some());
}
}