Skip to content

WIP: crash_log: Dump encrypted log on panic - #1711

Draft
Femi Adeyemi (femiatl) wants to merge 1 commit into
mainfrom
femia/wip/crashlog
Draft

Femi Adeyemi (femiatl) wants to merge 1 commit into
mainfrom
femia/wip/crashlog

Conversation

@femiatl

@femiatl Femi Adeyemi (femiatl) commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor
  1. Replace HOST_LOGGER with CRASH_LOGGER. It logs to VTL1 allocated memory instead of serial port and VTL0 ringbuffer. On debug builds, it optionally mirrors to the serial port.

  2. VTL0 will a use a new SetCrashDumpKey API to send LiteBox a public key that will be used for crash dump envelope encryption.

  3. On panic, the VTL1 logs are encrypted with a symmetric AES-256-GCM key, and that key itself is encrypted by the public key sent by VTL0. The crash dump envelope is then written to VTL0 ringbuffer in the following format (see CrashDumpHeader for details): CrashDumpHeader(AEAD) | Encrypted Key | Log Ciphertext | Tag

  4. Design Choices:

    • VTL1 logs are stored in a const-size ringbuffer available at boot. This implies some space in .bss/.data section.
    • Envelope cipher is prepared on public key provision to avoid RNG availability in panic path.
  5. TODOS:

  • On vault panic, what can be dumped, if any.
  • Test exceptions (div/0,... ), VTL0 panic paths.
  • Add certificate validation for VTL0 public key
  • VTL0 ringbuffer writes can be simplified if we insist on a page aligned buffer.

1. Replace HOST_LOGGER with CRASH_LOGGER. It logs to VTL1 allocated
   memory instead of serial port and VTL0 ringbuffer. On debug builds,
   it optionally mirrors to the serial port.

2. VTL0 will a use a new SetCrashDumpKey API to send LiteBox a public
   key that will be used for crash dump envelope encryption.

3. On panic, the VTL1 logs are encrypted with a symmetric AES-256-GCM
   key, and that key itself is encrypted by the public key sent by VTL0.
   The crash dump envelope is then written to VTL0 ringbuffer in the
   following format (see CrashDumpHeader for details):
   CrashDumpHeader(AEAD) | Encrypted Key | Log Ciphertext | Tag

4. Design Choices:
   - VTL1 logs are stored in a const-size ringbuffer available at
     boot. This implies some space in .bss/.data section.
   - Envelope cipher is prepared on public key provision to avoid
     RNG availability in panic path.

5. TODOS:
  - On vault panic, what can be dumped, if any.
  - Test exceptions (div/0,... ), VTL0 panic paths.
  - VTL0 ringbuffer writes can be simplified if we insist on
    a page aligned buffer.
@github-actions

Copy link
Copy Markdown

🤖 SemverChecks 🤖 ⚠️ Potential breaking API changes detected ⚠️

Click for details
--- failure enum_variant_added: enum variant added on exhaustive enum ---

Description:
A publicly-visible enum without #[non_exhaustive] has a new variant.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.51.0/src/lints/enum_variant_added.ron

Failed in:
  variant VsmFunction:SetCrashDumpKey in /home/runner/work/litebox/litebox/litebox_common_lvbs/src/lib.rs:81

--- failure trait_method_added: pub trait method added ---

Description:
A non-sealed public trait added a new method without a default implementation, which breaks downstream implementations of the trait
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-item-no-default
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.51.0/src/lints/trait_method_added.ron

Failed in:
  trait method litebox_common_lvbs::Vtl1Gate::set_crash_dump_key in file /home/runner/work/litebox/litebox/litebox_common_lvbs/src/lib.rs:909

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved provisioning, log retention, serialization, key-trust, and panic-coordination issues prevent reliable and secure crash dumping.

8 open issues
What changed in this PR

This PR introduces encrypted crash logging for LVBS, keeping logs in VTL1 memory and preparing an encrypted envelope for export to VTL0 on panic.

Changes:

  • Replaces the host logger with a fixed-size crash logger and optional debug serial mirroring.
  • Adds crash-dump key provisioning interfaces and RSA-wrapped AES-256-GCM encryption.
  • Connects panic handling to dump generation and updates dependencies and global-count limits.
File Description
litebox_runner_lvbs/​src/​main.rs Installs the crash logger and configures serial mirroring.
litebox_runner_lvbs/​src/​lib.rs Adds the dispatch arm and invokes dumping on panic.
litebox_platform_lvbs/​src/​mshv/​vsm.rs Implements public-key loading and envelope preparation.
litebox_platform_lvbs/​src/​mshv/​ringbuffer.rs Adds a TODO about buffer alignment requirements.
litebox_platform_lvbs/​src/​lib.rs Exposes the crash-log module.
litebox_platform_lvbs/​src/​host/​lvbs_impl.rs Makes the hardware seed helper crate-visible.
litebox_platform_lvbs/​src/​crash_log.rs Implements buffered logging, encryption, and dump serialization.
litebox_platform_lvbs/​src/​arch/​x86/​ioport.rs Removes ring-buffer forwarding and adds nonblocking panic serial output.
litebox_platform_lvbs/​Cargo.toml Adds logging and encryption dependencies.
litebox_common_lvbs/​src/​lib.rs Defines the crash-key call, gate method, and error.
dev_tests/​src/​ratchet.rs Adjusts global-count limits for logger relocation.
Cargo.lock Records the added cryptographic dependency graph.

Review effort: Balanced

self.buf[tail..tail + first_len].copy_from_slice(&data[..first_len]);
self.buf[..data.len() - first_len].copy_from_slice(&data[first_len..]);

self.head = (self.head + data.len()) % N;
Comment on lines +215 to +217
if self.panic_dump_started.swap(true, Ordering::SeqCst) {
serial_print_panic_string("Crash dump already progress");
return Err(VsmError::OutOfMemory);
let mut vtl0_buf = vtl0_buf.lock();
vtl0_buf.write(aead.as_bytes());
vtl0_buf.write(&envelope.wrapped_data_key);
vtl0_buf.write(&envelope.crash_dump_key_id);
Comment on lines +806 to +807
fn set_crash_dump_key(&self, key_pa: u64, key_len: u64) -> Result<(), VsmError> {
let key_pa = PhysAddr::try_new(key_pa).map_err(|_| VsmError::InvalidPhysicalAddress)?;
Err(VsmError::OperationNotSupported("Identity key generation"))
}
VsmFunction::OpteeMessage => Err(VsmError::OperationNotSupported("OP-TEE communication")),
VsmFunction::SetCrashDumpKey => Err(VsmError::OperationNotSupported("Set Crash Dump Key")),
Comment on lines +214 to +224
pub fn dump_on_panic(&self, _info: &PanicInfo) -> Result<(), VsmError> {
if self.panic_dump_started.swap(true, Ordering::SeqCst) {
serial_print_panic_string("Crash dump already progress");
return Err(VsmError::OutOfMemory);
}

let Some(envelope) = &*self.envelope.lock() else {
return Err(VsmError::InvalidKey);
};

let ring_buffer = &mut *self.ring_buf.lock();
Comment on lines +263 to +265
if litebox_util_log::format_record(&mut buf, record).is_ok() {
self.ring_buf.lock().write(buf.as_bytes());
}
Comment on lines +818 to +819
let seed = crate::host::lvbs_impl::rdrand_seed().ok_or(VsmError::InvalidKey)?;
let mut rng = rand_chacha::ChaCha20Rng::from_seed(seed);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants