feat(boot): gatekeeper gates boot (init→UI→gatekeeper→data); keystore disk + virtio-rng discovery; terminal READ_SECRET; storage SET_KEY; PageCount ≤8192, alloc cap gone; device window 0x01D0_0000; test-qemu types passcode over 2 boots

This commit is contained in:
2026-10-27 23:43:47 +01:00
parent b7ef67ffd8
commit 3b7d004285
36 changed files with 455 additions and 74 deletions

View File

@@ -67,18 +67,26 @@ impl Random for Counter {
/// An owner typing from a script; what was shown is kept.
struct Owner {
typing: VecDeque<&'static str>,
/// On the screen now.
shown: String,
/// Ever shown, cleared or not.
said: String,
}
impl Owner {
fn types(lines: &[&'static str]) -> Self {
Self { typing: lines.iter().copied().collect(), shown: String::new() }
Self { typing: lines.iter().copied().collect(), shown: String::new(), said: String::new() }
}
}
impl Prompt for Owner {
fn say(&mut self, text: &str) {
self.shown.push_str(text);
self.said.push_str(text);
}
/// What a fresh screen shows: nothing that came before.
fn clear(&mut self) {
self.shown.clear();
}
fn secret(&mut self, question: &str, out: &mut Secret) -> bool {
self.shown.push_str(question);
@@ -158,7 +166,7 @@ fn too_many_wrong_passcodes_wipe_the_keys_and_the_device_starts_fresh() {
guesses.extend(["5678", "5678", "", ""]);
let mut owner = Owner::types(&guesses);
let new = run_with(&mut dev, &mut owner).unwrap();
assert!(owner.shown.contains("One try left"));
assert!(owner.said.contains("One try left"));
assert!(owner.shown.ends_with("This device has no passcode yet. Choose one; it protects everything on it.\nNew passcode: Again: A duress passcode wipes the device when it is entered instead. Leave it empty for none.\nDuress passcode: Again: "));
assert_ne!(new.0, key, "the old master key is gone");
let mut old = Owner::types(&["1234"]);
@@ -173,6 +181,7 @@ fn the_duress_passcode_wipes_silently_and_the_device_looks_fresh() {
let mut owner = Owner::types(&["0000", "4321", "4321", "", ""]);
let new = run_with(&mut dev, &mut owner).unwrap();
assert!(!owner.shown.contains("Wrong"), "nothing tells it was a duress passcode");
assert!(owner.shown.starts_with("This device has no passcode yet"), "nor is the passcode prompt left showing");
assert!(owner.shown.contains("no passcode yet"));
assert_ne!(new.0, key);
}