1use crate::manifest::RvfManifest;
6use crate::signature::ML_DSA_65_PUBLIC_KEY_SIZE;
7use crate::stages::{Stage0Hardware, Stage1Verify, Stage2Create, Stage3Mount, Stage4Attest};
8use crate::witness_log::{WitnessLog, WitnessLogConfig};
9use crate::attestation::BootAttestation;
10use crate::capability_distribution::CapabilityDistribution;
11use ruvix_types::KernelError;
12use ruvix_cap::BootCapabilitySet;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
16#[repr(u8)]
17pub enum BootStage {
18 HardwareInit = 0,
20
21 RvfVerify = 1,
23
24 ObjectCreate = 2,
26
27 ComponentMount = 3,
29
30 FirstAttestation = 4,
32
33 Complete = 5,
35}
36
37impl BootStage {
38 #[inline]
40 #[must_use]
41 pub const fn as_str(&self) -> &'static str {
42 match self {
43 Self::HardwareInit => "Hardware Init",
44 Self::RvfVerify => "RVF Verify",
45 Self::ObjectCreate => "Object Create",
46 Self::ComponentMount => "Component Mount",
47 Self::FirstAttestation => "First Attestation",
48 Self::Complete => "Complete",
49 }
50 }
51}
52
53#[derive(Debug, Clone)]
55pub struct BootConfig {
56 pub public_key: [u8; ML_DSA_65_PUBLIC_KEY_SIZE],
58
59 pub witness_log_config: WitnessLogConfig,
61
62 pub verbose: bool,
64
65 pub platform_id_override: u64,
67}
68
69impl Default for BootConfig {
70 fn default() -> Self {
71 Self {
72 public_key: [0u8; ML_DSA_65_PUBLIC_KEY_SIZE],
73 witness_log_config: WitnessLogConfig::default(),
74 verbose: false,
75 platform_id_override: 0,
76 }
77 }
78}
79
80#[derive(Debug)]
82pub struct BootResult {
83 pub stage: BootStage,
85
86 pub hardware: Stage0Hardware,
88
89 pub manifest: Option<RvfManifest>,
91
92 pub boot_capabilities: Option<BootCapabilitySet>,
94
95 pub witness_log: Option<WitnessLog>,
97
98 pub capability_distribution: Option<CapabilityDistribution>,
100
101 pub boot_attestation: Option<BootAttestation>,
103
104 pub sec001_capability_drop: bool,
106}
107
108impl BootResult {
109 #[must_use]
111 fn new() -> Self {
112 Self {
113 stage: BootStage::HardwareInit,
114 hardware: Stage0Hardware::new(),
115 manifest: None,
116 boot_capabilities: None,
117 witness_log: None,
118 capability_distribution: None,
119 boot_attestation: None,
120 sec001_capability_drop: false,
121 }
122 }
123}
124
125pub struct BootLoader {
134 config: BootConfig,
136
137 result: BootResult,
139
140 stage0: Stage0Hardware,
142 stage1: Stage1Verify,
143 stage2: Stage2Create,
144 stage3: Stage3Mount,
145 stage4: Stage4Attest,
146}
147
148impl BootLoader {
149 #[must_use]
151 pub fn new(config: BootConfig) -> Self {
152 let mut stage1 = Stage1Verify::new();
153 stage1.set_public_key(&config.public_key);
154
155 Self {
156 config,
157 result: BootResult::new(),
158 stage0: Stage0Hardware::new(),
159 stage1,
160 stage2: Stage2Create::new(),
161 stage3: Stage3Mount::new(),
162 stage4: Stage4Attest::new(),
163 }
164 }
165
166 #[cfg(test)]
168 #[must_use]
169 pub fn test_loader() -> Self {
170 let config = BootConfig {
171 public_key: [0u8; ML_DSA_65_PUBLIC_KEY_SIZE],
172 witness_log_config: WitnessLogConfig::default(),
173 verbose: true,
174 platform_id_override: 0,
175 };
176
177 Self::new(config)
178 }
179
180 pub fn boot(&mut self, manifest_bytes: &[u8], signature: &[u8]) -> Result<&BootResult, KernelError> {
191 self.execute_stage0()?;
193
194 self.execute_stage1(manifest_bytes, signature)?;
196
197 self.execute_stage2()?;
199
200 self.execute_stage3()?;
202
203 self.execute_stage4()?;
205
206 self.result.stage = BootStage::Complete;
207
208 if self.config.verbose {
209 eprintln!("Boot complete");
210 }
211
212 Ok(&self.result)
213 }
214
215 fn execute_stage0(&mut self) -> Result<(), KernelError> {
217 if self.config.verbose {
218 eprintln!("Executing Stage 0: Hardware Init");
219 }
220
221 self.stage0.execute()?;
222 self.result.hardware = self.stage0.clone();
223 self.result.stage = BootStage::RvfVerify;
224
225 Ok(())
226 }
227
228 fn execute_stage1(&mut self, manifest_bytes: &[u8], signature: &[u8]) -> Result<(), KernelError> {
234 if self.config.verbose {
235 eprintln!("Executing Stage 1: RVF Verify");
236 }
237
238 self.stage1.execute(manifest_bytes, signature)?;
240
241 self.result.manifest = self.stage1.manifest.clone();
242 self.result.stage = BootStage::ObjectCreate;
243
244 Ok(())
245 }
246
247 fn execute_stage2(&mut self) -> Result<(), KernelError> {
249 if self.config.verbose {
250 eprintln!("Executing Stage 2: Object Create");
251 }
252
253 let manifest = self.result.manifest.as_ref()
254 .ok_or(KernelError::InternalError)?;
255
256 let physical_memory = self.result.hardware.physical_memory_bytes;
257
258 self.stage2.execute(manifest, physical_memory)?;
259
260 self.result.boot_capabilities = self.stage2.boot_capabilities.clone();
261 self.result.witness_log = self.stage2.witness_log.take();
262 self.result.stage = BootStage::ComponentMount;
263
264 Ok(())
265 }
266
267 fn execute_stage3(&mut self) -> Result<(), KernelError> {
269 if self.config.verbose {
270 eprintln!("Executing Stage 3: Component Mount");
271 }
272
273 let manifest = self.result.manifest.as_ref()
274 .ok_or(KernelError::InternalError)?;
275
276 let boot_caps = self.result.boot_capabilities.as_ref()
277 .ok_or(KernelError::InternalError)?;
278
279 self.stage3.execute(manifest, boot_caps)?;
280
281 self.result.capability_distribution = self.stage3.capability_distribution.clone();
282 self.result.sec001_capability_drop = self.stage3.capability_distribution
283 .as_ref()
284 .map(|d| d.root_dropped_to_minimum)
285 .unwrap_or(false);
286 self.result.stage = BootStage::FirstAttestation;
287
288 Ok(())
289 }
290
291 fn execute_stage4(&mut self) -> Result<(), KernelError> {
293 if self.config.verbose {
294 eprintln!("Executing Stage 4: First Attestation");
295 }
296
297 let manifest = self.result.manifest.as_ref()
298 .ok_or(KernelError::InternalError)?;
299
300 let boot_caps = self.result.boot_capabilities.as_ref()
301 .ok_or(KernelError::InternalError)?;
302
303 let witness_log = self.result.witness_log.as_mut()
304 .ok_or(KernelError::InternalError)?;
305
306 self.stage4.execute(manifest, witness_log, boot_caps)?;
307
308 self.result.boot_attestation = self.stage4.attestation.clone();
309
310 Ok(())
311 }
312
313 #[inline]
315 #[must_use]
316 pub fn current_stage(&self) -> BootStage {
317 self.result.stage
318 }
319
320 #[inline]
322 #[must_use]
323 pub fn result(&self) -> &BootResult {
324 &self.result
325 }
326
327 #[inline]
329 #[must_use]
330 pub fn sec001_compliant(&self) -> bool {
331 self.result.sec001_capability_drop
332 }
333}
334
335#[cfg(test)]
336mod tests {
337 use super::*;
338 use crate::signature::SIGNATURE_SIZE;
339
340 fn create_test_manifest() -> Vec<u8> {
341 let mut manifest = vec![0u8; 100];
342 manifest[0..4].copy_from_slice(b"RVF1");
343 manifest[4..6].copy_from_slice(&1u16.to_le_bytes());
344 manifest[6..8].copy_from_slice(&0u16.to_le_bytes());
345 manifest
346 }
347
348 fn create_test_signature(manifest: &[u8]) -> Vec<u8> {
349 use sha2::{Sha256, Digest};
350
351 let mut sig = vec![0u8; SIGNATURE_SIZE];
352 sig[0..4].copy_from_slice(b"TEST");
353
354 let mut hasher = Sha256::new();
355 hasher.update(manifest);
356 let hash = hasher.finalize();
357 sig[4..36].copy_from_slice(&hash);
358
359 sig
360 }
361
362 #[test]
363 fn test_boot_stage_ordering() {
364 assert!(BootStage::HardwareInit < BootStage::RvfVerify);
365 assert!(BootStage::RvfVerify < BootStage::ObjectCreate);
366 assert!(BootStage::ObjectCreate < BootStage::ComponentMount);
367 assert!(BootStage::ComponentMount < BootStage::FirstAttestation);
368 assert!(BootStage::FirstAttestation < BootStage::Complete);
369 }
370
371 #[test]
372 fn test_boot_config_default() {
373 let config = BootConfig::default();
374 assert_eq!(config.public_key, [0u8; ML_DSA_65_PUBLIC_KEY_SIZE]);
375 assert!(!config.verbose);
376 }
377
378 #[test]
379 fn test_full_boot_sequence() {
380 let mut loader = BootLoader::test_loader();
381
382 let manifest = create_test_manifest();
383 let signature = create_test_signature(&manifest);
384
385 let result = loader.boot(&manifest, &signature).unwrap();
386
387 assert_eq!(result.stage, BootStage::Complete);
388 assert!(result.manifest.is_some());
389 assert!(result.boot_capabilities.is_some());
390 assert!(result.witness_log.is_some());
391 assert!(result.boot_attestation.is_some());
392 assert!(result.sec001_capability_drop);
393 }
394
395 #[test]
396 fn test_boot_sec001_compliant() {
397 let mut loader = BootLoader::test_loader();
398
399 let manifest = create_test_manifest();
400 let signature = create_test_signature(&manifest);
401
402 loader.boot(&manifest, &signature).unwrap();
403
404 assert!(loader.sec001_compliant());
405 }
406
407 #[test]
408 fn test_boot_current_stage() {
409 let loader = BootLoader::test_loader();
410
411 assert_eq!(loader.current_stage(), BootStage::HardwareInit);
413 }
414
415 #[test]
416 #[should_panic(expected = "Boot signature verification failed")]
417 fn test_boot_invalid_signature_panics() {
418 let mut loader = BootLoader::test_loader();
419
420 let manifest = create_test_manifest();
421 let wrong_manifest = b"wrong manifest";
422 let signature = create_test_signature(wrong_manifest);
423
424 let _ = loader.boot(&manifest, &signature);
426 }
427
428 #[test]
429 fn test_boot_invalid_manifest() {
430 let mut loader = BootLoader::test_loader();
431
432 let manifest = b"XXXX";
434 let signature = vec![0u8; SIGNATURE_SIZE]; let result = loader.boot(manifest, &signature);
437
438 assert!(result.is_err());
439 assert_eq!(result.unwrap_err(), KernelError::InvalidManifest);
440 }
441}