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:
@@ -110,8 +110,12 @@ impl<'a> Launcher<'a> {
|
||||
if let Some(free) = self.served.iter_mut().find(|s| s.is_none()) {
|
||||
*free = Some((p.name, ep));
|
||||
}
|
||||
if let Some(device) = p.device {
|
||||
note = self.give(device, ep);
|
||||
for device in p.devices {
|
||||
note = self.give(*device, ep);
|
||||
}
|
||||
if p.unlocks {
|
||||
unlock(ep)?;
|
||||
note = ", the owner is in";
|
||||
}
|
||||
if console.is_some() {
|
||||
hand_over_console(ep);
|
||||
@@ -139,6 +143,8 @@ impl<'a> Launcher<'a> {
|
||||
let (dev, given, none): (BoardDevice, _, _) = match device {
|
||||
Device::Gpu => (self.devices.gpu, ", gpu handed over", ", no gpu"),
|
||||
Device::Input => (self.devices.input, ", input device handed over", ", no input device"),
|
||||
Device::Keystore => (self.devices.keystore, ", keystore handed over", ", no keystore"),
|
||||
Device::Random => (self.devices.random, ", randomness handed over", ", no randomness"),
|
||||
};
|
||||
match libkos::device::give_device(ep, dev).is_ok() && dev.mmio.is_some() {
|
||||
true => given,
|
||||
@@ -147,6 +153,23 @@ impl<'a> Launcher<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Waits for the gatekeeper behind `ep` to authenticate the owner, then
|
||||
/// passes the master key on to storage, which alone keeps it.
|
||||
fn unlock(ep: CapSlot) -> Result<(), &'static str> {
|
||||
use types::gatekeeper::{KEY, UNLOCK, reply};
|
||||
match syscall::request(ep, [UNLOCK, 0, 0, 0]) {
|
||||
Ok([reply::OK, ..]) => {}
|
||||
_ => return Err("the gatekeeper could not unlock"),
|
||||
}
|
||||
let mut key = syscall::request(ep, [KEY, 0, 0, 0]).map_err(|_| "the gatekeeper gave no key")?;
|
||||
let given = [0, 1].iter().all(|&half| {
|
||||
let words = [types::storage::op::SET_KEY, half, key[half * 2], key[half * 2 + 1]];
|
||||
syscall::request(crate::STORAGE_EP, words).is_ok_and(|r| r[0] == types::storage::reply::OK)
|
||||
});
|
||||
key.fill(0);
|
||||
if given { Ok(()) } else { Err("storage would not take the key") }
|
||||
}
|
||||
|
||||
/// From here on init prints through the log server, like everyone else,
|
||||
/// and holds no console of its own.
|
||||
fn hand_over_console(log: CapSlot) {
|
||||
|
||||
Reference in New Issue
Block a user