mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
enable gateware updates when no root keys are present
This commit is contained in:
parent
3aeec85e06
commit
ead5bd7dac
6 changed files with 115 additions and 0 deletions
|
|
@ -11,6 +11,18 @@
|
|||
"zh": "输入密码 软件更新 安全含义:至关重要 ",
|
||||
"en-tts": "Enter update password. This password is critically important."
|
||||
},
|
||||
"rootkeys.blind_update": {
|
||||
"en": "No root keys detected. Shall we copy the staged gateware anyways, overwriting the current image?",
|
||||
"ja": "ルートキーが検出されませんでした。 とにかくステージングされたゲートウェアをコピーして、現在のイメージを上書きしませんか?",
|
||||
"zh": "未检测到根密钥。 我们是否要复制暂存的网关软件,覆盖当前映像?",
|
||||
"en-tts": "No root keys detected. Shall we copy the staged gateware anyways, overwriting the current image?"
|
||||
},
|
||||
"rootkeys.wrong_state": {
|
||||
"en": "System in an unexpected state. Aborting.",
|
||||
"ja": "予期しない状態のシステム。 中止します。",
|
||||
"zh": "系统处于意外状态。 中止。",
|
||||
"en-tts": "System in an unexpected state. Aborting."
|
||||
},
|
||||
"rootkeys.already_init": {
|
||||
"en": "Root keys already initialized.",
|
||||
"ja": "ルートキーはすでに初期化されています。",
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ pub(crate) enum Opcode {
|
|||
SuspendResume = 32,
|
||||
|
||||
Quit = 33,
|
||||
|
||||
/// makes a "blind copy" of the staged gateware. This will destroy root keys,
|
||||
/// but the call will not succeed if the image was provisioned.
|
||||
UxBlindCopy = 34,
|
||||
}
|
||||
|
||||
#[derive(Debug, num_derive::FromPrimitive, num_derive::ToPrimitive, PartialEq, Eq)]
|
||||
|
|
@ -93,6 +97,8 @@ pub enum RootkeyResult {
|
|||
KeyError = 1,
|
||||
IntegrityError = 2,
|
||||
FlashError = 3,
|
||||
/// enclave is in the wrong state to do the requested operation
|
||||
StateError = 4,
|
||||
}
|
||||
|
||||
/// AES operation definitions
|
||||
|
|
|
|||
|
|
@ -1527,6 +1527,32 @@ impl<'a> RootKeys {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// blind-copy a staged gateware to the boot location. This can only be done if not root keys
|
||||
/// have been initialized. This routine exists just to make the UX flow consistent between
|
||||
/// unprovisioned and provisioned devices.
|
||||
pub(crate) fn do_gateware_provision_uninitialized(&mut self, rootkeys_modal: &mut Modal, main_cid: xous::CID) -> Result<(), RootkeyResult> {
|
||||
if self.is_initialized() {
|
||||
return Err(RootkeyResult::StateError);
|
||||
}
|
||||
let mut progress_action = Slider::new(main_cid, Opcode::UxGutter.to_u32().unwrap(),
|
||||
0, 100, 10, Some("%"), 0, true, true
|
||||
);
|
||||
progress_action.set_is_password(true);
|
||||
rootkeys_modal.modify(
|
||||
Some(ActionType::Slider(progress_action)),
|
||||
Some(t!("rootkeys.gwup_starting", xous::LANG)), false,
|
||||
None, true, None);
|
||||
rootkeys_modal.activate();
|
||||
xous::yield_slice(); // give some time to the GAM to render
|
||||
let mut pb = ProgressBar::new(rootkeys_modal, &mut progress_action);
|
||||
pb.set_percentage(1);
|
||||
self.ticktimer.sleep_ms(250).expect("couldn't show final message");
|
||||
self.make_gateware_backup(Some(&mut pb), true)?;
|
||||
pb.set_percentage(100);
|
||||
self.ticktimer.sleep_ms(250).expect("couldn't show final message");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// copy data from a source region to a destination region, re-encrypting and patching as we go along.
|
||||
/// the region/region_base should be specified for the destination oracle
|
||||
///
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ impl RootKeys {
|
|||
pub fn get_update_gateware_op(&self) -> u32 {
|
||||
Opcode::UxUpdateGateware.to_u32().unwrap()
|
||||
}
|
||||
pub fn get_blind_copy_gateware_op(&self) -> u32 {
|
||||
Opcode::UxBlindCopy.to_u32().unwrap()
|
||||
}
|
||||
pub fn get_try_selfsign_op(&self) -> u32 {
|
||||
Opcode::UxSelfSignXous.to_u32().unwrap()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -591,6 +591,9 @@ fn main() -> ! {
|
|||
Err(RootkeyResult::FlashError) => {
|
||||
modals.show_notification(t!("rootkeys.init.fail_burn", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::StateError) => {
|
||||
modals.show_notification(t!("rootkeys.wrong_state", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(Opcode::UxTryReboot) => {
|
||||
|
|
@ -643,6 +646,53 @@ fn main() -> ! {
|
|||
xous::Message::new_scalar(Opcode::UxTryReboot.to_usize().unwrap(), 0, 0, 0, 0)
|
||||
).expect("couldn't initiate dialog box");
|
||||
}
|
||||
Some(Opcode::UxBlindCopy) => {
|
||||
modals.add_list_item(t!("rootkeys.gwup.yes", xous::LANG)).expect("modals error");
|
||||
modals.add_list_item(t!("rootkeys.gwup.no", xous::LANG)).expect("modals error");
|
||||
match modals.get_radiobutton(t!("rootkeys.blind_update", xous::LANG)) {
|
||||
Ok(response) => {
|
||||
if response == t!("rootkeys.gwup.no", xous::LANG) {
|
||||
continue;
|
||||
} if response != t!("rootkeys.gwup.yes", xous::LANG) {
|
||||
log::error!("got unexpected response from radio box: {:?}", response);
|
||||
continue;
|
||||
} else {
|
||||
// just proceed forward!
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
log::error!("modals error, aborting");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let result = keys.do_gateware_provision_uninitialized(&mut rootkeys_modal, main_cid);
|
||||
// the stop emoji, when sent to the slider action bar in progress mode, will cause it to close and relinquish focus
|
||||
rootkeys_modal.key_event(['🛑', '\u{0000}', '\u{0000}', '\u{0000}']);
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
modals.show_notification(t!("rootkeys.gwup.finished", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::AlignmentError) => {
|
||||
modals.show_notification(t!("rootkeys.init.fail_alignment", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::KeyError) => {
|
||||
// probably a bad password, purge it, so the user can try again
|
||||
keys.purge_password(PasswordType::Update);
|
||||
modals.show_notification(t!("rootkeys.init.fail_key", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::IntegrityError) => {
|
||||
modals.show_notification(t!("rootkeys.init.fail_verify", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::FlashError) => {
|
||||
modals.show_notification(t!("rootkeys.init.fail_burn", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::StateError) => {
|
||||
modals.show_notification(t!("rootkeys.wrong_state", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Opcode::UxUpdateGateware) => {
|
||||
// steps:
|
||||
// - check update signature "Inspecting gateware update, this will take a moment..."
|
||||
|
|
@ -808,6 +858,9 @@ fn main() -> ! {
|
|||
Err(RootkeyResult::FlashError) => {
|
||||
modals.show_notification(t!("rootkeys.init.fail_burn", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::StateError) => {
|
||||
modals.show_notification(t!("rootkeys.wrong_state", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Opcode::UxSelfSignXous) => {
|
||||
|
|
@ -883,6 +936,9 @@ fn main() -> ! {
|
|||
Err(RootkeyResult::FlashError) => {
|
||||
modals.show_notification(t!("rootkeys.init.fail_burn", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::StateError) => {
|
||||
modals.show_notification(t!("rootkeys.wrong_state", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Opcode::UxAesEnsurePassword) => msg_blocking_scalar_unpack!(msg, key_index, _, _, _, {
|
||||
|
|
@ -1088,6 +1144,9 @@ fn main() -> ! {
|
|||
Err(RootkeyResult::FlashError) => {
|
||||
modals.show_notification(t!("rootkeys.init.fail_burn", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
Err(RootkeyResult::StateError) => {
|
||||
modals.show_notification(t!("rootkeys.wrong_state", xous::LANG), None).expect("modals error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,10 +75,19 @@ pub fn create_main_menu(keys: Arc<Mutex<RootKeys>>, menu_management_sid: xous::S
|
|||
action_payload: MenuPayload::Scalar([0, 0, 0, 0]),
|
||||
close_on_select: true,
|
||||
});
|
||||
menuitems.push(MenuItem {
|
||||
name: String::from_str(t!("mainmenu.provision_gateware", xous::LANG)),
|
||||
action_conn: Some(key_conn),
|
||||
// note this is using the blind copy opcode -- makes a copy without installing keys
|
||||
action_opcode: keys.lock().unwrap().get_blind_copy_gateware_op(),
|
||||
action_payload: MenuPayload::Scalar([0, 0, 0, 0]),
|
||||
close_on_select: true,
|
||||
});
|
||||
} else {
|
||||
menuitems.push(MenuItem {
|
||||
name: String::from_str(t!("mainmenu.provision_gateware", xous::LANG)),
|
||||
action_conn: Some(key_conn),
|
||||
// note this is using the update opcode -- makes a copy while installing keys
|
||||
action_opcode: keys.lock().unwrap().get_update_gateware_op(),
|
||||
action_payload: MenuPayload::Scalar([0, 0, 0, 0]),
|
||||
close_on_select: true,
|
||||
|
|
|
|||
Loading…
Reference in a new issue