diff --git a/Cargo.lock b/Cargo.lock index ceac3f278..44be69827 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,7 @@ dependencies = [ "log-server", "opaque-debug", "xous", + "zeroize", ] [[package]] @@ -1477,6 +1478,7 @@ dependencies = [ "xous", "xous-ipc", "xous-names", + "zeroize", ] [[package]] @@ -2302,9 +2304,9 @@ checksum = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5" [[package]] name = "zeroize" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" dependencies = [ "zeroize_derive", ] diff --git a/services/aes/Cargo.toml b/services/aes/Cargo.toml index d28ae32ad..ebcad3094 100644 --- a/services/aes/Cargo.toml +++ b/services/aes/Cargo.toml @@ -13,6 +13,7 @@ cipher = "0.3" ctr = { version = "0.7", optional = true } opaque-debug = "0.3" hex-literal = "0.2" +zeroize = "1.4.1" [features] compact = [] # Reduce code size at the cost of slower performance diff --git a/services/root-keys/Cargo.toml b/services/root-keys/Cargo.toml index 16d03a279..e88166b2b 100644 --- a/services/root-keys/Cargo.toml +++ b/services/root-keys/Cargo.toml @@ -22,6 +22,7 @@ xous-ipc = {path = "../../xous-ipc"} num-derive = {version = "0.3", default-features = false} num-traits = {version = "0.2", default-features = false} rkyv = {version = "0.4.3", default-features = false, features = ["const_generics"]} +zeroize = "1.4.1" # bcrypt cipher = "0.3" diff --git a/services/root-keys/src/api.rs b/services/root-keys/src/api.rs index a4c0b0d46..e6a68efa9 100644 --- a/services/root-keys/src/api.rs +++ b/services/root-keys/src/api.rs @@ -44,8 +44,7 @@ pub(crate) enum Opcode { UxSignXousRun, /// Ux AES calls - //UxAesRequestPw, - //UxAesRun, + //UxAesEnsurePassword, // General Ux calls UxGutter, // NOP for UX calls that require a destination @@ -96,6 +95,7 @@ pub enum RootkeyResult { /// AES operation definitions pub use cipher::{BlockCipher, consts::U16}; +use zeroize::Zeroize; /// Selects which key to use for the decryption/encryption oracle. /// currently only one type is available, the User key, but dozens more @@ -106,17 +106,20 @@ pub enum AesRootkeyType { NoneSpecified = 0xff, } -#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Copy, Clone)] +#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Zeroize)] +#[zeroize(drop)] pub enum AesBlockType { SingleBlock([u8; 16]), ParBlock([[u8; 16]; 16]), } -#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Copy, Clone)] +#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Zeroize)] +#[zeroize(drop)] pub enum AesOpType { Encrypt, Decrypt, } -#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Copy, Clone)] +#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Zeroize)] +#[zeroize(drop)] pub struct AesOp { /// the caller can try to request "any" index, but it's checked inside the oracle first. pub key_index: u8, diff --git a/services/root-keys/src/implementation.rs b/services/root-keys/src/implementation.rs index ab01067e3..7692df14b 100644 --- a/services/root-keys/src/implementation.rs +++ b/services/root-keys/src/implementation.rs @@ -682,6 +682,9 @@ impl<'a> RootKeys { KeyRomLocs::USER_KEY => { let mut key_enc = self.read_key_256(KeyRomLocs::USER_KEY); let pcache: &PasswordCache = unsafe{& *(self.pass_cache.as_ptr() as *const PasswordCache)}; + if pcache.hashed_boot_pw_valid == 0 { + log::warn!("boot password isn't valid! Returning bogus results."); + } for (key, &pw) in key_enc.iter_mut().zip(pcache.hashed_boot_pw.iter()) { *key = *key ^ pw; @@ -707,6 +710,9 @@ impl<'a> RootKeys { KeyRomLocs::USER_KEY => { let mut key_enc = self.read_key_256(KeyRomLocs::USER_KEY); let pcache: &PasswordCache = unsafe{& *(self.pass_cache.as_ptr() as *const PasswordCache)}; + if pcache.hashed_boot_pw_valid == 0 { + log::warn!("boot password isn't valid! Returning bogus results."); + } for (key, &pw) in key_enc.iter_mut().zip(pcache.hashed_boot_pw.iter()) { *key = *key ^ pw; diff --git a/services/root-keys/src/lib.rs b/services/root-keys/src/lib.rs index 4af70ceed..444a56e14 100644 --- a/services/root-keys/src/lib.rs +++ b/services/root-keys/src/lib.rs @@ -52,19 +52,6 @@ impl RootKeys { Opcode::UxSelfSignXous.to_u32().unwrap() } - - /// this function causes the staging gateware to be provisioned with a copy of our keys, - /// while being encrypted to the AES key indicated inside the KEYROM - pub fn provision_and_encrypt_staging_gateware(&mut self) -> Result<(), xous::Error> { - unimplemented!(); - } - - /// this function causes the staging gateware to be copied to the boot gateware region. - /// it can report progress of the operation by sending a message to an optional ScalarHook - pub fn copy_staging_to_boot_gateware(&mut self) -> Result<(), xous::Error> { - unimplemented!(); - } - /// this function takes a boot gateware that has a "null" key (all zeros) and: /// 0. confirms that JTAG is accessible by reading out the ID, and that the eFuse is writeable, and all 0's /// 1. prompts of the update password, and confirms that the existing efuse key decrypts to 0. if not -- we were already fused, abort. @@ -80,6 +67,11 @@ impl RootKeys { unimplemented!(); } + /// this initiates an attempt to update passwords. User must unlock their device first, and can cancel out if not expected. + pub fn try_update_password(&mut self, _which: PasswordType) -> Result<(), xous::Error> { + unimplemented!(); + } + /// checks to see if the KEYROM has been initialized, and if not, generates keys. In the process of doing so, the user will be /// prompted to enter passwords. It also automatically self-signs everything -- presumably, if you were comfortable enough to /// use this firmware to make your keys, you also trusted it. @@ -103,11 +95,6 @@ impl RootKeys { } } - /// this initiates an attempt to update passwords. User must unlock their device first, and can cancel out if not expected. - pub fn try_update_password(&mut self, _which: PasswordType) -> Result<(), xous::Error> { - unimplemented!(); - } - /// this will check the signature on the gateware. /// returns None if no keys have been initialized /// returns true if the gateware passes, false if it fails