mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
add some basic image integrity checking code
this doesn't protect against malicious tampering (because the public key is the developer key) but it will at least catch correctness errors in USB upload and filesystem behavior.
This commit is contained in:
parent
8aa633641f
commit
2437712b7b
1 changed files with 76 additions and 1 deletions
|
|
@ -1,12 +1,18 @@
|
|||
use core::convert::TryInto;
|
||||
|
||||
use cramium_hal::iox::{IoGpio, IoSetup, Iox, IoxPort, IoxValue};
|
||||
use cramium_hal::minigfx::{FrameBuffer, Point};
|
||||
use cramium_hal::sh1107::Mono;
|
||||
use cramium_hal::udma;
|
||||
use cramium_hal::usb::driver::UsbDeviceState;
|
||||
use ed25519_dalek::{Digest, Signature, VerifyingKey};
|
||||
use sha2::Sha512;
|
||||
use simple_fatfs::PathBuf;
|
||||
use utralib::generated::*;
|
||||
|
||||
use crate::SIGBLOCK_SIZE;
|
||||
use crate::platform::cramium::gfx;
|
||||
use crate::platform::cramium::sha512_digest::Sha512Prehash;
|
||||
use crate::platform::cramium::usb;
|
||||
use crate::platform::cramium::usb::SliceCursor;
|
||||
|
||||
|
|
@ -18,6 +24,20 @@ use crate::platform::cramium::usb::SliceCursor;
|
|||
// to detect if the device is unplugged.
|
||||
const DISCONNECT_STATE: u32 = 0x40b;
|
||||
|
||||
// loader is not updateable here because we're XIP. But we can update these other images:
|
||||
const SWAP_NAME: &'static str = "SWAP.IMG";
|
||||
const KERNEL_NAME: &'static str = "XOUS.IMG";
|
||||
const DEV_PUBKEY: [u8; 32] = [
|
||||
0x1c, 0x9b, 0xea, 0xe3, 0x2a, 0xea, 0xc8, 0x75, 0x07, 0xc1, 0x80, 0x94, 0x38, 0x7e, 0xff, 0x1c, 0x74,
|
||||
0x61, 0x42, 0x82, 0xaf, 0xfd, 0x81, 0x52, 0xd8, 0x71, 0x35, 0x2e, 0xdf, 0x3f, 0x58, 0xbb,
|
||||
];
|
||||
#[repr(C)]
|
||||
struct SignatureInFlash {
|
||||
pub version: u32,
|
||||
pub signed_len: u32,
|
||||
pub signature: [u8; 64],
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum KeyPress {
|
||||
Up,
|
||||
|
|
@ -193,7 +213,62 @@ pub fn process_update(perclk: u32) {
|
|||
match fs.read_dir(PathBuf::from("/")) {
|
||||
Ok(dir) => {
|
||||
for entry in dir {
|
||||
crate::println!("file: {:?}", entry);
|
||||
crate::println!("{:?}", entry);
|
||||
if let Some(file_name) = entry.path().file_name() {
|
||||
if file_name.to_ascii_uppercase() == KERNEL_NAME {
|
||||
match fs.get_file(entry.path().clone()) {
|
||||
Ok(f) => {
|
||||
let sector_offset = f.sector_offset();
|
||||
crate::println!("sector offset: {}", sector_offset);
|
||||
let disk_access = usb::conjure_disk();
|
||||
crate::println!(
|
||||
"{:x?}",
|
||||
&disk_access[sector_offset as usize * 512
|
||||
..sector_offset as usize * 512 + 32]
|
||||
);
|
||||
let pubkey = VerifyingKey::from_bytes(&DEV_PUBKEY)
|
||||
.expect("public key was not valid");
|
||||
crate::println!("pubkey as reconstituted: {:x?}", pubkey);
|
||||
|
||||
let k_start = sector_offset as usize * 512;
|
||||
let sig_region = &disk_access
|
||||
[k_start..k_start + core::mem::size_of::<SignatureInFlash>()];
|
||||
let sig_rec: &SignatureInFlash = (sig_region.as_ptr()
|
||||
as *const SignatureInFlash)
|
||||
.as_ref()
|
||||
.unwrap(); // this pointer better not be null, we just created it!
|
||||
let sig = Signature::from_bytes(&sig_rec.signature);
|
||||
|
||||
let kern_len = sig_rec.signed_len as usize;
|
||||
crate::println!("recorded kernel len: {} bytes", kern_len);
|
||||
crate::println!(
|
||||
"verifying with signature {:x?}",
|
||||
sig_rec.signature
|
||||
);
|
||||
crate::println!("verifying with pubkey {:x?}", pubkey.to_bytes());
|
||||
|
||||
let mut h: Sha512 = Sha512::new();
|
||||
let image = &disk_access[k_start + SIGBLOCK_SIZE
|
||||
..k_start + SIGBLOCK_SIZE + sig_rec.signed_len as usize];
|
||||
h.update(&image);
|
||||
let hash = h.finalize();
|
||||
let mut ph = Sha512Prehash::new();
|
||||
ph.set_prehash(hash.as_slice().try_into().unwrap());
|
||||
match pubkey.verify_prehashed(ph, None, &sig) {
|
||||
Ok(()) => crate::println!("Kernel image is good!"),
|
||||
Err(e) => {
|
||||
crate::println!("error verifying signature: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
crate::println!("Couldn't access image: {:?}", e);
|
||||
}
|
||||
}
|
||||
} else if file_name.to_ascii_lowercase() == SWAP_NAME {
|
||||
crate::println!("Found swap image");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue