feat(storage): per-app/owner/system encryption live: gatekeeper hands seed + fresh flag, storage unlocks layer, init seeds areas from factory/ (empties on new key); rmdir op; test-qemu checks sealed home + reboot persistence
This commit is contained in:
@@ -151,14 +151,21 @@ fn setup(ks: &mut impl Keystore, rng: &mut impl Random, prompt: &mut impl Prompt
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
/// The owner is in: the master key, and whether it is new (a fresh
|
||||
/// device, or one just wiped), so nothing sealed under an old one exists.
|
||||
pub struct Unlocked {
|
||||
pub key: Key,
|
||||
pub fresh: bool,
|
||||
}
|
||||
|
||||
/// Authenticates the owner and returns the master key: setting one up on
|
||||
/// a fresh device, wiping on duress or too many failures (the device then
|
||||
/// looks fresh, and is set up anew).
|
||||
pub fn run(ks: &mut impl Keystore, rng: &mut impl Random, prompt: &mut impl Prompt, params: KdfParams, memory: &mut [Block]) -> Result<Key, Failure> {
|
||||
pub fn run(ks: &mut impl Keystore, rng: &mut impl Random, prompt: &mut impl Prompt, params: KdfParams, memory: &mut [Block]) -> Result<Unlocked, Failure> {
|
||||
loop {
|
||||
let (record, next) = load(ks)?;
|
||||
let Some(record) = record else {
|
||||
return setup(ks, rng, prompt, params, memory);
|
||||
return setup(ks, rng, prompt, params, memory).map(|key| Unlocked { key, fresh: true });
|
||||
};
|
||||
if record.must_wipe() {
|
||||
wipe(ks, &record, next, rng)?;
|
||||
@@ -174,7 +181,7 @@ pub fn run(ks: &mut impl Keystore, rng: &mut impl Random, prompt: &mut impl Prom
|
||||
match record.unlock(typed.as_bytes(), memory) {
|
||||
Outcome::Real(key) => {
|
||||
store(ks, 1 - next, &counted.next(|r| r.failures = 0))?;
|
||||
return Ok(key);
|
||||
return Ok(Unlocked { key, fresh: false });
|
||||
}
|
||||
Outcome::Duress => {
|
||||
// Recorded as worn out first: a wipe cut short resumes.
|
||||
|
||||
Reference in New Issue
Block a user