Verified Commit 9d837a34 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Implement unlocking encrypted RedoxFS

parent e1d45a1b
......@@ -17,5 +17,5 @@ stage3:
align 512, db 0
.end:
; the maximum size of the boot loader portion is 256 KiB
times 262144-($-$$) db 0
; the maximum size of the boot loader portion is 384 KiB
times (384*1024)-($-$$) db 0
......@@ -16,6 +16,7 @@ extern crate alloc;
extern crate uefi_std as std;
use alloc::{
string::String,
vec::Vec,
};
use core::{
......@@ -229,6 +230,57 @@ fn select_mode<
mode_opt
}
fn redoxfs<
D: Disk,
M: Iterator<Item=OsMemoryEntry>,
V: Iterator<Item=OsVideoMode>
>(os: &mut dyn Os<D, M, V>) -> redoxfs::FileSystem<D> {
let attempts = 10;
for attempt in 0..=attempts {
let mut password_opt = None;
if attempt > 0 {
print!("\rRedoxFS password ({}/{}): ", attempt, attempts);
let mut password = String::new();
loop {
match os.get_key() {
OsKey::Backspace | OsKey::Delete => if ! password.is_empty() {
print!("\x08 \x08");
password.pop();
},
OsKey::Char(c) => {
print!("*");
password.push(c)
},
OsKey::Enter => break,
_ => (),
}
}
// Erase password information
while os.get_text_position().0 > 0 {
print!("\x08 \x08");
}
if ! password.is_empty() {
password_opt = Some(password);
}
}
match os.filesystem(password_opt.as_ref().map(|x| x.as_bytes())) {
Ok(fs) => return fs,
Err(err) => match err.errno {
// Incorrect password, try again
syscall::ENOKEY => (),
_ => {
panic!("Failed to open RedoxFS: {}", err);
}
}
}
}
panic!("RedoxFS out of unlock attempts");
}
fn main<
D: Disk,
M: Iterator<Item=OsMemoryEntry>,
......@@ -236,7 +288,7 @@ fn main<
>(os: &mut dyn Os<D, M, V>) -> (usize, KernelArgs) {
println!("Redox OS Bootloader {} on {}", env!("CARGO_PKG_VERSION"), os.name());
let mut fs = os.filesystem();
let mut fs = redoxfs(os);
print!("RedoxFS ");
for i in 0..fs.header.uuid().len() {
......
......@@ -85,13 +85,12 @@ impl Os<
4096
}
fn filesystem(&self) -> redoxfs::FileSystem<DiskBios> {
fn filesystem(&self, password_opt: Option<&[u8]>) -> syscall::Result<redoxfs::FileSystem<DiskBios>> {
let disk = DiskBios::new(u8::try_from(self.boot_disk).unwrap(), self.thunk13);
//TODO: get block from partition table
let block = crate::MIBI as u64 / redoxfs::BLOCK_SIZE;
redoxfs::FileSystem::open(disk, None, Some(block), false)
.expect("Failed to open RedoxFS")
redoxfs::FileSystem::open(disk, password_opt, Some(block), false)
}
fn memory(&self) -> MemoryMapIter {
......@@ -144,8 +143,13 @@ impl Os<
0x4D => OsKey::Right,
0x48 => OsKey::Up,
0x50 => OsKey::Down,
0x0E => OsKey::Backspace,
0x53 => OsKey::Delete,
0x1C => OsKey::Enter,
_ => OsKey::Other,
_ => match data.eax as u8 {
0 => OsKey::Other,
b => OsKey::Char(b as char),
}
}
}
......
......@@ -94,6 +94,9 @@ impl fmt::Write for Vga {
self.y -= 1;
}
match c {
'\x08' => if self.x > 0 {
self.x -= 1;
},
'\r' => {
self.x = 0;
},
......
......@@ -20,7 +20,10 @@ pub enum OsKey {
Right,
Up,
Down,
Backspace,
Delete,
Enter,
Char(char),
Other,
}
......@@ -62,7 +65,7 @@ pub trait Os<
fn page_size(&self) -> usize;
fn filesystem(&self) -> redoxfs::FileSystem<D>;
fn filesystem(&self, password_opt: Option<&[u8]>) -> syscall::Result<redoxfs::FileSystem<D>>;
fn memory(&self) -> M;
......
......@@ -82,23 +82,25 @@ impl Os<
4096
}
fn filesystem(&self) -> redoxfs::FileSystem<DiskEfi> {
fn filesystem(&self, password_opt: Option<&[u8]>) -> syscall::Result<redoxfs::FileSystem<DiskEfi>> {
for (i, block_io) in DiskEfi::all().into_iter().enumerate() {
if !block_io.0.Media.LogicalPartition {
continue;
}
match redoxfs::FileSystem::open(block_io, None, Some(0), false) {
Ok(ok) => return ok,
match redoxfs::FileSystem::open(block_io, password_opt, Some(0), false) {
Ok(ok) => return Ok(ok),
Err(err) => match err.errno {
// Ignore header not found error
syscall::ENOENT => (),
// Print any other errors
_ => log::error!("Failed to open RedoxFS on block I/O {}: {}", i, err),
// Return any other errors
_ => {
return Err(err)
}
}
}
}
panic!("Failed to find RedoxFS");
Err(syscall::Error::new(syscall::ENOENT))
}
fn memory(&self) -> MemoryMapIter {
......@@ -170,13 +172,18 @@ impl Os<
match key.ScanCode {
0 => match key.UnicodeChar {
8 => OsKey::Backspace,
13 => OsKey::Enter,
_ => OsKey::Other,
w => match char::from_u32(w as u32) {
Some(c) => OsKey::Char(c),
None => OsKey::Other,
},
},
1 => OsKey::Up,
2 => OsKey::Down,
3 => OsKey::Right,
4 => OsKey::Left,
8 => OsKey::Delete,
_ => OsKey::Other,
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment