diff --git a/precursors/rom.db b/precursors/rom.db index 820a353c5..b1ea6a50a 100755 --- a/precursors/rom.db +++ b/precursors/rom.db @@ -1,128 +1,128 @@ -KEYROM 0 A SLICE_X36Y50 b'7139253efdee5437' -KEYROM 0 B SLICE_X36Y50 b'971240e7cb57d092' -KEYROM 0 C SLICE_X36Y50 b'1dd9845c5beaed5f' -KEYROM 0 D SLICE_X36Y50 b'b3b9d3cf5df61115' -KEYROM 1 A SLICE_X37Y50 b'406106417c8c7a65' -KEYROM 1 B SLICE_X37Y50 b'90c050c8b1e6af8c' -KEYROM 1 C SLICE_X37Y50 b'4894ab9eff8c8120' -KEYROM 1 D SLICE_X37Y50 b'b2eebf9478771fc9' -KEYROM 2 A SLICE_X36Y51 b'04286997eaf93401' -KEYROM 2 B SLICE_X36Y51 b'7e96f2c01e044565' -KEYROM 2 C SLICE_X36Y51 b'5a1e7c59ba4eeefb' -KEYROM 2 D SLICE_X36Y51 b'ed892258d64749ae' -KEYROM 3 A SLICE_X37Y51 b'7ea1b6851d9cb941' -KEYROM 3 B SLICE_X37Y51 b'6dfc6d5e02565f98' -KEYROM 3 C SLICE_X37Y51 b'5e3f36393b0d8d31' -KEYROM 3 D SLICE_X37Y51 b'ce2d479fa075d0f6' -KEYROM 4 A SLICE_X36Y52 b'ea97bf9e2e05b6ea' -KEYROM 4 B SLICE_X36Y52 b'a4e6631085dc8aed' -KEYROM 4 C SLICE_X36Y52 b'7eeb7b41817d34bf' -KEYROM 4 D SLICE_X36Y52 b'5912d16b8f528ecd' -KEYROM 5 A SLICE_X37Y52 b'0f1f162a35644658' -KEYROM 5 B SLICE_X37Y52 b'f984ab0d583d99ee' -KEYROM 5 C SLICE_X37Y52 b'ade3aa1429ca0183' -KEYROM 5 D SLICE_X37Y52 b'26bb13534f96d856' -KEYROM 6 A SLICE_X36Y53 b'8a6d0ef306aa6667' -KEYROM 6 B SLICE_X36Y53 b'c2bbdf7002d5be1d' -KEYROM 6 C SLICE_X36Y53 b'567dd7a83e29038d' -KEYROM 6 D SLICE_X36Y53 b'763405f2b1815c60' -KEYROM 7 A SLICE_X37Y53 b'7ceb7ca31ca9613e' -KEYROM 7 B SLICE_X37Y53 b'e075bde3985aa0c9' -KEYROM 7 C SLICE_X37Y53 b'fa698ee2b6dccd3f' -KEYROM 7 D SLICE_X37Y53 b'c5f451b0972f6ed1' -KEYROM 8 A SLICE_X36Y54 b'6f2da448148a8f49' -KEYROM 8 B SLICE_X36Y54 b'140c9ad2ae031c7b' -KEYROM 8 C SLICE_X36Y54 b'01fe3806885c92b9' -KEYROM 8 D SLICE_X36Y54 b'0fabd3bcc7b48917' -KEYROM 9 A SLICE_X37Y54 b'a325c72db086a6f6' -KEYROM 9 B SLICE_X37Y54 b'3bfd6fec12deecca' -KEYROM 9 C SLICE_X37Y54 b'3f1c20a20c7f9634' -KEYROM 9 D SLICE_X37Y54 b'67e4119d7c96a841' -KEYROM 10 A SLICE_X36Y55 b'17d01d48c0af1b80' -KEYROM 10 B SLICE_X36Y55 b'637e8ad69ee66cd3' -KEYROM 10 C SLICE_X36Y55 b'4b92d8a3bed42d84' -KEYROM 10 D SLICE_X36Y55 b'18b8ee879ba38a7e' -KEYROM 11 A SLICE_X37Y55 b'cce61555a1c8dcd6' -KEYROM 11 B SLICE_X37Y55 b'ac96df91741b0e43' -KEYROM 11 C SLICE_X37Y55 b'90ca2278f5a39578' -KEYROM 11 D SLICE_X37Y55 b'0684d8d2a065f6be' -KEYROM 12 A SLICE_X36Y56 b'808d9d0a5a7b01a4' -KEYROM 12 B SLICE_X36Y56 b'd4b3c9e452c72cb3' -KEYROM 12 C SLICE_X36Y56 b'970c458641fce1d1' -KEYROM 12 D SLICE_X36Y56 b'b4648f6136e64267' -KEYROM 13 A SLICE_X37Y56 b'29683729d8d7ee49' -KEYROM 13 B SLICE_X37Y56 b'da772edc07a0f23b' -KEYROM 13 C SLICE_X37Y56 b'8b09fdf54713dc4f' -KEYROM 13 D SLICE_X37Y56 b'84a8ffb1f1d83030' -KEYROM 14 A SLICE_X36Y57 b'7d31c2576a245640' -KEYROM 14 B SLICE_X36Y57 b'26712a039b8a397e' -KEYROM 14 C SLICE_X36Y57 b'a6f8f7be4f11002a' -KEYROM 14 D SLICE_X36Y57 b'8307e7557577111e' -KEYROM 15 A SLICE_X37Y57 b'fad7bc009408da13' -KEYROM 15 B SLICE_X37Y57 b'543fa23206dbe7b8' -KEYROM 15 C SLICE_X37Y57 b'ffcda1667acce717' -KEYROM 15 D SLICE_X37Y57 b'33cc4d7182ae9814' -KEYROM 16 A SLICE_X36Y58 b'4183a9f725df0ea1' -KEYROM 16 B SLICE_X36Y58 b'255004c9126605fd' -KEYROM 16 C SLICE_X36Y58 b'8eb282956cf6f85b' -KEYROM 16 D SLICE_X36Y58 b'32a4abd08e03f3a3' -KEYROM 17 A SLICE_X37Y58 b'5f33a858a287c5d8' -KEYROM 17 B SLICE_X37Y58 b'0197ed73c600a445' -KEYROM 17 C SLICE_X37Y58 b'6ba1e43c71757825' -KEYROM 17 D SLICE_X37Y58 b'b55b5d9ac9534337' -KEYROM 18 A SLICE_X36Y59 b'4ba57b36af113d3d' -KEYROM 18 B SLICE_X36Y59 b'c44455dec99281b1' -KEYROM 18 C SLICE_X36Y59 b'5ff51d04a2e23c93' -KEYROM 18 D SLICE_X36Y59 b'903a750c19dbbd7d' -KEYROM 19 A SLICE_X37Y59 b'de7b79327ea2009f' -KEYROM 19 B SLICE_X37Y59 b'2c83e749de6bdbab' -KEYROM 19 C SLICE_X37Y59 b'c9099a49e0a7962e' -KEYROM 19 D SLICE_X37Y59 b'4e0506ce2c222f53' -KEYROM 20 A SLICE_X36Y60 b'd3547cebff1734b2' -KEYROM 20 B SLICE_X36Y60 b'c77c0610cc2f3391' -KEYROM 20 C SLICE_X36Y60 b'a74034f532b4f128' -KEYROM 20 D SLICE_X36Y60 b'69f1ca4530332a1d' -KEYROM 21 A SLICE_X37Y60 b'50c0a9850d7d9510' -KEYROM 21 B SLICE_X37Y60 b'790e363c1fa363e0' -KEYROM 21 C SLICE_X37Y60 b'5c7ae6a5dc6e0a25' -KEYROM 21 D SLICE_X37Y60 b'a477b153a4dce16d' -KEYROM 22 A SLICE_X36Y61 b'befde63548ca8db3' -KEYROM 22 B SLICE_X36Y61 b'8dd6865f2a7d2c84' -KEYROM 22 C SLICE_X36Y61 b'a340c5dd4ee12769' -KEYROM 22 D SLICE_X36Y61 b'53c4ff8c438a27a7' -KEYROM 23 A SLICE_X37Y61 b'a71e06f0e983c86d' -KEYROM 23 B SLICE_X37Y61 b'874dfb61381f6aed' -KEYROM 23 C SLICE_X37Y61 b'92a40f86bad5a032' -KEYROM 23 D SLICE_X37Y61 b'fdd5969e64d3c1bc' -KEYROM 24 A SLICE_X36Y62 b'613906ed3d19211f' -KEYROM 24 B SLICE_X36Y62 b'800fbaba78d3d7f4' -KEYROM 24 C SLICE_X36Y62 b'f7f74840480f9d67' -KEYROM 24 D SLICE_X36Y62 b'09bac089a69da8c3' -KEYROM 25 A SLICE_X37Y62 b'882292c3377103d2' -KEYROM 25 B SLICE_X37Y62 b'aaebf2003815bf39' -KEYROM 25 C SLICE_X37Y62 b'8afaa0c9b4b61b5c' -KEYROM 25 D SLICE_X37Y62 b'42682e75cc042514' -KEYROM 26 A SLICE_X36Y63 b'aa394990a60fafdc' -KEYROM 26 B SLICE_X36Y63 b'bad8c1e3576df432' -KEYROM 26 C SLICE_X36Y63 b'11e72091a52b86dd' -KEYROM 26 D SLICE_X36Y63 b'cb67b8e302736449' -KEYROM 27 A SLICE_X37Y63 b'821a9549e8b1abe8' -KEYROM 27 B SLICE_X37Y63 b'ed911d6cf4a2911e' -KEYROM 27 C SLICE_X37Y63 b'400c3f94f9068455' -KEYROM 27 D SLICE_X37Y63 b'65f6d884b2053c8e' -KEYROM 28 A SLICE_X36Y64 b'b3f027e3ac1624c5' -KEYROM 28 B SLICE_X36Y64 b'35829056dfe53606' -KEYROM 28 C SLICE_X36Y64 b'ae55134511cb97f9' -KEYROM 28 D SLICE_X36Y64 b'4f1f9333a74027aa' -KEYROM 29 A SLICE_X37Y64 b'6efeeab089a09501' -KEYROM 29 B SLICE_X37Y64 b'7b2e802098b11a60' -KEYROM 29 C SLICE_X37Y64 b'7f63244980975d0d' -KEYROM 29 D SLICE_X37Y64 b'0eccde94c05979f7' -KEYROM 30 A SLICE_X36Y65 b'4ac3eecf185df444' -KEYROM 30 B SLICE_X36Y65 b'75e82366f18c159f' -KEYROM 30 C SLICE_X36Y65 b'aeffd4c4b8974f63' -KEYROM 30 D SLICE_X36Y65 b'64637baa3d0ff963' -KEYROM 31 A SLICE_X37Y65 b'f59b2721520d2513' -KEYROM 31 B SLICE_X37Y65 b'f004c1a5acb4a035' -KEYROM 31 C SLICE_X37Y65 b'4200431f9a9fe273' -KEYROM 31 D SLICE_X37Y65 b'9e17232480cc6907' +KEYROM 0 A SLICE_X36Y50 b'1f7d5c8c28f314e0' +KEYROM 0 B SLICE_X36Y50 b'cd50fee6651ae040' +KEYROM 0 C SLICE_X36Y50 b'6ff668fdf9565108' +KEYROM 0 D SLICE_X36Y50 b'830674aee37f9f9b' +KEYROM 1 A SLICE_X37Y50 b'37da3de15bd6e6b9' +KEYROM 1 B SLICE_X37Y50 b'f997b3fcfc86bf95' +KEYROM 1 C SLICE_X37Y50 b'8292d24999a8675e' +KEYROM 1 D SLICE_X37Y50 b'49f5179908cce603' +KEYROM 2 A SLICE_X36Y51 b'28dac5f0c9ff1b0a' +KEYROM 2 B SLICE_X36Y51 b'541b80d41c077b17' +KEYROM 2 C SLICE_X36Y51 b'36141805498d1ab9' +KEYROM 2 D SLICE_X36Y51 b'100f2c3ec1f209ce' +KEYROM 3 A SLICE_X37Y51 b'91d9d04c3ce094ba' +KEYROM 3 B SLICE_X37Y51 b'66fd8d828177370b' +KEYROM 3 C SLICE_X37Y51 b'fc4a884b9967a8b8' +KEYROM 3 D SLICE_X37Y51 b'74263e0bcca9d78d' +KEYROM 4 A SLICE_X36Y52 b'd4092e42bd876ec4' +KEYROM 4 B SLICE_X36Y52 b'458357e6f0a87855' +KEYROM 4 C SLICE_X36Y52 b'bd7b07f4d0bd7a80' +KEYROM 4 D SLICE_X36Y52 b'ae22758a8efcac96' +KEYROM 5 A SLICE_X37Y52 b'd76966646659121e' +KEYROM 5 B SLICE_X37Y52 b'952089bf586d30d3' +KEYROM 5 C SLICE_X37Y52 b'8dadcee0fa5e98c0' +KEYROM 5 D SLICE_X37Y52 b'7a59e508065c22c2' +KEYROM 6 A SLICE_X36Y53 b'5044db8b385b32d6' +KEYROM 6 B SLICE_X36Y53 b'f8a03d7dc98539d0' +KEYROM 6 C SLICE_X36Y53 b'090591cd3acafb61' +KEYROM 6 D SLICE_X36Y53 b'bfd6b28858341284' +KEYROM 7 A SLICE_X37Y53 b'0b10286549096bae' +KEYROM 7 B SLICE_X37Y53 b'90890314b7b75e50' +KEYROM 7 C SLICE_X37Y53 b'186cdb7a085da5fb' +KEYROM 7 D SLICE_X37Y53 b'eeeb1bbcce37d679' +KEYROM 8 A SLICE_X36Y54 b'53ddf808f4a57d0a' +KEYROM 8 B SLICE_X36Y54 b'f6242d3cd388fb22' +KEYROM 8 C SLICE_X36Y54 b'bfa39389828be47e' +KEYROM 8 D SLICE_X36Y54 b'42d645ad56babdef' +KEYROM 9 A SLICE_X37Y54 b'68ec449243617109' +KEYROM 9 B SLICE_X37Y54 b'64cc9a836bbd9ab9' +KEYROM 9 C SLICE_X37Y54 b'2da4535fc3b8cd62' +KEYROM 9 D SLICE_X37Y54 b'f453233b01c02389' +KEYROM 10 A SLICE_X36Y55 b'208a262b17e19096' +KEYROM 10 B SLICE_X36Y55 b'c57768e323cf411b' +KEYROM 10 C SLICE_X36Y55 b'435fddc6c3943799' +KEYROM 10 D SLICE_X36Y55 b'42583ccd8c74f84b' +KEYROM 11 A SLICE_X37Y55 b'c96f86d274a201c5' +KEYROM 11 B SLICE_X37Y55 b'5623ad369a3300d5' +KEYROM 11 C SLICE_X37Y55 b'93d078de9cf8c3df' +KEYROM 11 D SLICE_X37Y55 b'2ea8e2539621ec02' +KEYROM 12 A SLICE_X36Y56 b'2bd341898ee5c4c7' +KEYROM 12 B SLICE_X36Y56 b'25002714990e2c71' +KEYROM 12 C SLICE_X36Y56 b'89b7939021840440' +KEYROM 12 D SLICE_X36Y56 b'3b008e7a32187940' +KEYROM 13 A SLICE_X37Y56 b'b520a7884502d3f2' +KEYROM 13 B SLICE_X37Y56 b'f1b729c408df8d32' +KEYROM 13 C SLICE_X37Y56 b'ba1f594efb9e2ffa' +KEYROM 13 D SLICE_X37Y56 b'7330326a52acb733' +KEYROM 14 A SLICE_X36Y57 b'1b9483c92c08b805' +KEYROM 14 B SLICE_X36Y57 b'fd47fe6e46289b59' +KEYROM 14 C SLICE_X36Y57 b'84879efba301cee3' +KEYROM 14 D SLICE_X36Y57 b'ae86e46e76dd1d0a' +KEYROM 15 A SLICE_X37Y57 b'27ffec3d820851ad' +KEYROM 15 B SLICE_X37Y57 b'1e32dd006575b9e7' +KEYROM 15 C SLICE_X37Y57 b'9b8d3fe5165e8867' +KEYROM 15 D SLICE_X37Y57 b'708095fc3cc73aeb' +KEYROM 16 A SLICE_X36Y58 b'254bdbea626135b7' +KEYROM 16 B SLICE_X36Y58 b'fd06decb9a44df8c' +KEYROM 16 C SLICE_X36Y58 b'1fd7ae8d9f02ae89' +KEYROM 16 D SLICE_X36Y58 b'dcc6cd1452cf3865' +KEYROM 17 A SLICE_X37Y58 b'285952040153db1a' +KEYROM 17 B SLICE_X37Y58 b'fc8134e2f7f25a81' +KEYROM 17 C SLICE_X37Y58 b'49add5fa95794c12' +KEYROM 17 D SLICE_X37Y58 b'6e7a1675c47a34e0' +KEYROM 18 A SLICE_X36Y59 b'2a11fc1fdd8f91f1' +KEYROM 18 B SLICE_X36Y59 b'ba337fddad3ea191' +KEYROM 18 C SLICE_X36Y59 b'ac395869e30c32c1' +KEYROM 18 D SLICE_X36Y59 b'6b673302a51ea151' +KEYROM 19 A SLICE_X37Y59 b'ec6c59f05df74c65' +KEYROM 19 B SLICE_X37Y59 b'd4c8e32f9e20d5a8' +KEYROM 19 C SLICE_X37Y59 b'94af413b93b278e8' +KEYROM 19 D SLICE_X37Y59 b'59ae467219e625e6' +KEYROM 20 A SLICE_X36Y60 b'298d00fe31752994' +KEYROM 20 B SLICE_X36Y60 b'4da0232e13a762c2' +KEYROM 20 C SLICE_X36Y60 b'96cdcf13538c67d4' +KEYROM 20 D SLICE_X36Y60 b'fab31db5b565c910' +KEYROM 21 A SLICE_X37Y60 b'7e97a6932d26a70f' +KEYROM 21 B SLICE_X37Y60 b'ae59ea152172e0e0' +KEYROM 21 C SLICE_X37Y60 b'4456332279ae9e6f' +KEYROM 21 D SLICE_X37Y60 b'a14a1ad1a870e491' +KEYROM 22 A SLICE_X36Y61 b'd7fecfb8c4010176' +KEYROM 22 B SLICE_X36Y61 b'f91a43cad066c86e' +KEYROM 22 C SLICE_X36Y61 b'c6fca7f327d84a77' +KEYROM 22 D SLICE_X36Y61 b'f3b341f02d88ea4a' +KEYROM 23 A SLICE_X37Y61 b'6fac8686d0861c6a' +KEYROM 23 B SLICE_X37Y61 b'74b8c5a8111418d3' +KEYROM 23 C SLICE_X37Y61 b'e5d864418e1ff7be' +KEYROM 23 D SLICE_X37Y61 b'81a082474880864c' +KEYROM 24 A SLICE_X36Y62 b'5b1d82284902e6a8' +KEYROM 24 B SLICE_X36Y62 b'270708629eea7714' +KEYROM 24 C SLICE_X36Y62 b'49b07f01454557ed' +KEYROM 24 D SLICE_X36Y62 b'ffdf0db09bdf8fb3' +KEYROM 25 A SLICE_X37Y62 b'fcf8742b799998c9' +KEYROM 25 B SLICE_X37Y62 b'491260ba728edc1f' +KEYROM 25 C SLICE_X37Y62 b'f7d01328326ad783' +KEYROM 25 D SLICE_X37Y62 b'2598a4db915e1589' +KEYROM 26 A SLICE_X36Y63 b'f2b30894064a5cfd' +KEYROM 26 B SLICE_X36Y63 b'861d7b04cd6f612d' +KEYROM 26 C SLICE_X36Y63 b'dce04fa11be76e64' +KEYROM 26 D SLICE_X36Y63 b'fee82fd1ceb7852f' +KEYROM 27 A SLICE_X37Y63 b'6b6e69d71ff7a619' +KEYROM 27 B SLICE_X37Y63 b'4704f62af50bfcfc' +KEYROM 27 C SLICE_X37Y63 b'b5edac6ef23bf396' +KEYROM 27 D SLICE_X37Y63 b'b20bdb1dfec4b6bb' +KEYROM 28 A SLICE_X36Y64 b'4bf7d00186980be5' +KEYROM 28 B SLICE_X36Y64 b'675fc8e16f9ff8ba' +KEYROM 28 C SLICE_X36Y64 b'86509354f4fd9848' +KEYROM 28 D SLICE_X36Y64 b'181b7a89b6a8c84c' +KEYROM 29 A SLICE_X37Y64 b'd2b830b6dfa74164' +KEYROM 29 B SLICE_X37Y64 b'94ba4a686e20ce3e' +KEYROM 29 C SLICE_X37Y64 b'490e9e7276cd0a0f' +KEYROM 29 D SLICE_X37Y64 b'cf21fbe7af07bfa8' +KEYROM 30 A SLICE_X36Y65 b'1bd5e9501a5046ec' +KEYROM 30 B SLICE_X36Y65 b'62250c595be56137' +KEYROM 30 C SLICE_X36Y65 b'1c753f7b7f791cc3' +KEYROM 30 D SLICE_X36Y65 b'ecefe631d309e771' +KEYROM 31 A SLICE_X37Y65 b'50c25e328d8f0ac5' +KEYROM 31 B SLICE_X37Y65 b'11eb83c88ff68e2c' +KEYROM 31 C SLICE_X37Y65 b'7f5bd3b64e53bac9' +KEYROM 31 D SLICE_X37Y65 b'e46af779ee5d20a3' diff --git a/precursors/soc.svd b/precursors/soc.svd index c2e7af9ac..84a9b42f8 100755 --- a/precursors/soc.svd +++ b/precursors/soc.svd @@ -3,7 +3,7 @@ litex SOC - + 8 32 @@ -3584,7 +3584,7 @@ inject too fast.]]> SEED1 0x0000 - 0x356326ec + 0x1e0a17d9 32 @@ -3599,7 +3599,7 @@ inject too fast.]]> SEED0 0x0004 - 0x6d0d21ea + 0x7f08f543 32 diff --git a/precursors/soc_csr.bin b/precursors/soc_csr.bin index 56dc9523e..e4d4d96f3 100755 Binary files a/precursors/soc_csr.bin and b/precursors/soc_csr.bin differ diff --git a/services/gam/src/modal.rs b/services/gam/src/modal.rs index 2bb05293a..46e078552 100644 --- a/services/gam/src/modal.rs +++ b/services/gam/src/modal.rs @@ -1068,6 +1068,7 @@ pub enum ActionType { CheckBoxes, Slider, Notification, + ConsoleInput } //#[derive(Debug)] @@ -1533,4 +1534,49 @@ impl<'a, 'b> ProgressBar<'a, 'b> { self.subtask_end_percent = subtask_end_percent; self.update_ui(self.subtask_start_percent); // this will redraw the UI if the start percent is different from the current } +} + + +/// This is a specialty structure that takes input from the serial console and records it to a string. +#[derive(Debug, Copy, Clone)] +pub struct ConsoleInput { + pub action_conn: xous::CID, + pub action_opcode: u32, + pub action_payload: TextEntryPayload, +} +impl ConsoleInput { + pub fn new(action_conn: xous::CID, action_opcode: u32) -> Self { + ConsoleInput { + action_conn, + action_opcode, + action_payload: TextEntryPayload::new(), + } + } +} +impl ActionApi for ConsoleInput { + fn set_action_opcode(&mut self, op: u32) {self.action_opcode = op} + fn height(&self, _glyph_height: i16, margin: i16) -> i16 { + margin + } + fn redraw(&self, _at_height: i16, _modal: &Modal) { + // has nothing + } + fn key_action(&mut self, k: char) -> (Option>, bool) { + log::trace!("key_action: {}", k); + match k { + '\u{0}' => { + // ignore null messages + } + '∴' | '\u{d}' => { + let buf = Buffer::into_buf(self.action_payload).expect("couldn't convert message to payload"); + buf.send(self.action_conn, self.action_opcode).map(|_| ()).expect("couldn't send action message"); + return (None, true) + } + _ => { // text entry + self.action_payload.0.push(k).expect("ran out of space storing password"); + log::trace!("****update payload: {}", self.action_payload.0); + } + } + (None, false) + } } \ No newline at end of file diff --git a/services/root-keys/Cargo.toml b/services/root-keys/Cargo.toml index e88166b2b..6b9aac87e 100644 --- a/services/root-keys/Cargo.toml +++ b/services/root-keys/Cargo.toml @@ -63,7 +63,7 @@ utralib = { path = "../../utralib"} [features] hazardous-debug = [] # this feature enables the printing of secret materials for debug purposes -default = ["hazardous-debug"] +default = [] [lib] test = true diff --git a/services/root-keys/locales/i18n.json b/services/root-keys/locales/i18n.json index 0b08e19b1..3a69cce4b 100644 --- a/services/root-keys/locales/i18n.json +++ b/services/root-keys/locales/i18n.json @@ -179,6 +179,31 @@ "zh": "更新完成重启应用", "en-audio": "Gateware update finished. Reboot at your earliest convenience." }, + "rootkeys.bbram.confirm": { + "en": "Connect provisioning helper,\nthen press enter.\nRefer to https://github.com/betrusted-io/betrusted-wiki/wiki for details.", + "zh": "立即连接配置助手。请参阅 https://github.com/betrusted-io/betrusted-wiki/wiki 了解详情。", + "en-audio": "Connect provisioning helper then press enter.\nRefer to https://github.com/betrusted-io/betrusted-wiki/wiki for details." + }, + "rootkeys.bbram.finished": { + "en": "BBRAM helper should have\nrebooted the device.\nThere was a problem with\nthe procedure!", + "zh": "**missing**", + "en-audio": "BBRAM helper should have rebooted the device, you should not see this message!" + }, + "rootkeys.bbram.failed_restore": { + "en": "Something went wrong.\nRestoring from backup...\n", + "zh": "出了点问题,从备份中恢复...", + "en-audio": "Something went wrong, restoring from backup." + }, + "rootkeys.console_input": { + "en": "Communicating with helper...\nPress enter to abort.", + "zh": "与助手通信,按 Enter 中止", + "en-audio": "Communicating with helper. Press enter to abort." + }, + "rootkeys.bbram.no_helper": { + "en": "No BBRAM helper found.\nRefer to https://github.com/betrusted-io/betrusted-wiki/wiki for help.", + "zh": "没有找到 BBRAM helper。参考https://github.com/betrusted-io/betrusted-wiki/wiki。", + "en-audio": "No BBRAM helper found. Refer to https://github.com/betrusted-io/betrusted-wiki/wiki for help." + }, "rootkeys.get_signing_password": { "en": "Password request\nSoftware update key\nSecurity: Critical\nWhy: Sign Xous", "zh": "输入密码\n软件更新\n安全含义:至关重要 ", diff --git a/services/root-keys/src/api.rs b/services/root-keys/src/api.rs index 0c0a6c126..776755067 100644 --- a/services/root-keys/src/api.rs +++ b/services/root-keys/src/api.rs @@ -15,8 +15,10 @@ pub(crate) enum Opcode { IsEfuseSecured, /// quick check to see if the JTAG can read its IDCODE IsJtagWorking, - /// initiate an AES operation - AesOperation, + /// initiate an AES oracle operation + AesOracle, + /// create new FPGA keys; provisioning requires a slave device to be connected that can run the JTAG sequence + BbramProvision, TestUx, @@ -48,6 +50,12 @@ pub(crate) enum Opcode { UxAesPasswordPolicy, UxAesEnsureReturn, + /// Ux BBRAM flow + UxBbramCheckHelper, + UxBbramCheckReturn, + UxBbramPasswordReturn, + UxBbramRun, + // General Ux calls UxGutter, // NOP for UX calls that require a destination UxGetPolicy, diff --git a/services/root-keys/src/implementation.rs b/services/root-keys/src/implementation.rs index 1fdd44d7f..26efc83f1 100644 --- a/services/root-keys/src/implementation.rs +++ b/services/root-keys/src/implementation.rs @@ -1,5 +1,6 @@ mod oracle; use oracle::*; +pub use oracle::FpgaKeySource; use utralib::generated::*; use crate::api::*; @@ -43,6 +44,22 @@ const CSR_CSV_OFFSET: usize = 0x27_7000; /// offset of the gateware self-signature area const SELFSIG_OFFSET: usize = 0x27_F000; +/// This structure is mapped into the password cache page and can be zero-ized at any time +/// we avoid using fancy Rust structures because everything has to "make sense" after a forced zero-ization +/// The "password" here is generated as follows: +/// `user plaintext (up to first 72 bytes) -> bcrypt (24 bytes) -> sha512trunc256 -> [u8; 32]` +/// The final sha512trunc256 expansion is because we will use this to XOR against secret keys stored in +/// the KEYROM that may be up to 256 bits in length. For shorter keys, the hashed password is simply truncated. +#[repr(C)] +struct PasswordCache { + hashed_boot_pw: [u8; 32], + hashed_boot_pw_valid: u32, // non-zero for valid + hashed_update_pw: [u8; 32], + hashed_update_pw_valid: u32, + fpga_key: [u8; 32], + fpga_key_valid: u32, +} + #[repr(C)] struct SignatureInFlash { pub version: u32, @@ -100,22 +117,6 @@ pub(crate) mod keyrom_config { pub const INITIALIZED: KeyField = KeyField::new(1, 27); } -/// This structure is mapped into the password cache page and can be zero-ized at any time -/// we avoid using fancy Rust structures because everything has to "make sense" after a forced zero-ization -/// The "password" here is generated as follows: -/// `user plaintext (up to first 72 bytes) -> bcrypt (24 bytes) -> sha512trunc256 -> [u8; 32]` -/// The final sha512trunc256 expansion is because we will use this to XOR against secret keys stored in -/// the KEYROM that may be up to 256 bits in length. For shorter keys, the hashed password is simply truncated. -#[repr(C)] -struct PasswordCache { - hashed_boot_pw: [u8; 32], - hashed_boot_pw_valid: u32, // non-zero for valid - hashed_update_pw: [u8; 32], - hashed_update_pw_valid: u32, - fpga_key: [u8; 32], - fpga_key_valid: u32, -} - /// helper routine that will reverse the order of bits. uses a divide-and-conquer approach. pub(crate) fn bitflip(input: &[u8], output: &mut [u8]) { assert!((input.len() % 4 == 0) && (output.len() % 4 == 0) && (input.len() == output.len())); @@ -364,6 +365,25 @@ impl<'a> RootKeys { return Some(true) } } + pub fn fpga_key_source(&self) -> FpgaKeySource { + let mut words = self.gateware()[..4096].chunks(4); + loop { + if let Some(word) = words.next() { + let cwd = u32::from_be_bytes(word[0..4].try_into().unwrap()); + if cwd == BITSTREAM_CTL0_CMD { + let ctl0 = u32::from_be_bytes(words.next().unwrap()[0..4].try_into().unwrap()); + if ctl0 & 0x8000_0000 == 0 { + return FpgaKeySource::Bbram + } else { + return FpgaKeySource::Efuse + } + } + } else { + log::error!("didn't find FpgaKeySource in plaintext header"); + panic!("didn't find FpgaKeySource in plaintext header"); + } + } + } pub fn is_jtag_working(&self) -> bool { if self.jtag.get_id().unwrap() == jtag::XCS750_IDCODE { true @@ -423,6 +443,33 @@ impl<'a> RootKeys { *d = keyword; } } + fn replace_fpga_key(&mut self) { + let pcache: &mut PasswordCache = unsafe{&mut *(self.pass_cache.as_mut_ptr() as *mut PasswordCache)}; + if self.is_initialized() { + assert!(pcache.hashed_update_pw_valid != 0, "update password was not set before calling replace_fpga_key"); + } + // build a new key into the pcache + for dst_lw in pcache.fpga_key.chunks_mut(8).into_iter() { // 64 bit chunks + for (dst, &src) in dst_lw.iter_mut().zip(self.trng.get_u64().unwrap().to_be_bytes().iter()) { + *dst = src; + } + } + + // now encrypt the key, and store it into the sensitive_data for access later on by the patching routine + if self.is_initialized() { + for (dst, (key, pw)) in + self.sensitive_data.borrow_mut().as_slice_mut::()[KeyRomLocs::FPGA_KEY as usize .. KeyRomLocs::FPGA_KEY as usize + 8].iter_mut().zip( + pcache.fpga_key.chunks(4).into_iter().zip(pcache.hashed_update_pw.chunks(4).into_iter())) { + *dst = u32::from_be_bytes(key[0..4].try_into().unwrap()) ^ u32::from_be_bytes(pw[0..4].try_into().unwrap()); + } + } else { + for (dst, key) in + self.sensitive_data.borrow_mut().as_slice_mut::()[KeyRomLocs::FPGA_KEY as usize .. KeyRomLocs::FPGA_KEY as usize + 8].iter_mut().zip( + pcache.fpga_key.chunks(4).into_iter()) { + *dst = u32::from_be_bytes(key[0..4].try_into().unwrap()); + } + } + } pub fn suspend(&mut self) { match self.boot_password_policy { @@ -704,18 +751,16 @@ impl<'a> RootKeys { #[cfg(feature = "hazardous-debug")] self.debug_print_key(KeyRomLocs::FPGA_KEY as usize, 256, "FPGA key before encryption: "); // before we encrypt it, stash a copy in our password cache, as we'll need it later on to encrypt the bitstream - for (word, key) in self.sensitive_data.borrow_mut().as_slice_mut::()[KeyRomLocs::FPGA_KEY as usize..KeyRomLocs::FPGA_KEY as usize + 256/(size_of::()*8)].iter() - .zip(pcache.fpga_key.chunks_mut(4).into_iter()) { - for (&s, d) in word.to_be_bytes().iter().zip(key.iter_mut()) { - *d = s; - } + for (&src, dst) in self.read_key_256(KeyRomLocs::FPGA_KEY).iter() + .zip(pcache.fpga_key.iter_mut()) { + *dst = src; } pcache.fpga_key_valid = 1; // now encrypt it in the staging area - for (word, key_word) in self.sensitive_data.borrow_mut().as_slice_mut::()[KeyRomLocs::FPGA_KEY as usize..KeyRomLocs::FPGA_KEY as usize + 256/(size_of::()*8)].iter_mut() + for (word, hashed_pass) in self.sensitive_data.borrow_mut().as_slice_mut::()[KeyRomLocs::FPGA_KEY as usize..KeyRomLocs::FPGA_KEY as usize + 256/(size_of::()*8)].iter_mut() .zip(pcache.hashed_update_pw.chunks(4).into_iter()) { - *word = *word ^ u32::from_be_bytes(key_word.try_into().unwrap()); + *word = *word ^ u32::from_be_bytes(hashed_pass.try_into().unwrap()); } // allocate a decryption oracle for the FPGA bitstream. This will fail early if the FPGA key is wrong. @@ -815,7 +860,7 @@ impl<'a> RootKeys { // in the staging area, so this step should be skipped. pb.update_text(t!("rootkeys.init.backup_gateware", xous::LANG)); pb.rebase_subtask_percentage(30, 50); - self.make_gateware_backup(Some(&mut pb))?; + self.make_gateware_backup(Some(&mut pb), false)?; log::debug!("making source oracle"); let mut src_oracle = match BitstreamOracle::new(&pcache.fpga_key, &pcache.fpga_key, self.staging(), self.staging_base()) { @@ -900,7 +945,7 @@ impl<'a> RootKeys { } } - pub fn do_gateware_update(&mut self, rootkeys_modal: &mut Modal, main_cid: xous::CID) -> Result<(), RootkeyResult> { + pub fn do_gateware_update(&mut self, rootkeys_modal: &mut Modal, main_cid: xous::CID, provision_bbram: bool) -> Result<(), RootkeyResult> { // make sure the system is sane self.xns_interlock(); self.spinor.set_staging_write_protect(true).expect("couldn't protect the staging area"); @@ -922,7 +967,7 @@ impl<'a> RootKeys { // decrypt the FPGA key using the stored password let pcache: &mut PasswordCache = unsafe{&mut *(self.pass_cache.as_mut_ptr() as *mut PasswordCache)}; - if pcache.hashed_update_pw_valid == 0 { + if pcache.hashed_update_pw_valid == 0 && self.is_initialized() { self.purge_password(PasswordType::Update); log::error!("no password was set going into the update routine"); #[cfg(feature = "hazardous-debug")] @@ -957,15 +1002,47 @@ impl<'a> RootKeys { #[cfg(feature = "hazardous-debug")] log::debug!("trying to make a keypair from {:x?}", keypair_bytes); // Keypair zeroizes on drop - let keypair = Keypair::from_bytes(&keypair_bytes).map_err(|_| RootkeyResult::KeyError)?; + let keypair: Option = if provision_bbram && !self.is_initialized() { + // don't try to derive signing keys if we're doing BBRAM provisioning on an otherwise blank device + None + } else { + Some(Keypair::from_bytes(&keypair_bytes).map_err(|_| RootkeyResult::KeyError)?) + }; log::debug!("keypair success"); // stage the keyrom data for patching self.populate_sensitive_data(); + let mut old_key_storage: [u8; 32] = [0; 32]; + let old_key = if provision_bbram { + pb.set_percentage(3); + if self.is_initialized() { + // make a backup copy of the old key, so we can use it to decrypt the gateware before re-encrypting it + for (&src, dst) in pcache.fpga_key.iter().zip(old_key_storage.iter_mut()) { + *dst = src; + } + } + self.replace_fpga_key(); - pb.set_percentage(3); + // we transmit the BBRAM key at this point -- because if there's going to be a failure, + // we'd rather know it now before moving on. Three copies are sent to provide some + // check on the integrity of the key. + log::info!("BBKEY|: {:?}", &pcache.fpga_key); + log::info!("BBKEY|: {:?}", &pcache.fpga_key); + log::info!("BBKEY|: {:?}", &pcache.fpga_key); + log::info!("{}", crate::CONSOLE_SENTINEL); + &old_key_storage + } else { + &pcache.fpga_key + }; + + pb.set_percentage(4); log::debug!("making destination oracle"); - let mut dst_oracle = match BitstreamOracle::new(&pcache.fpga_key, &pcache.fpga_key, self.gateware(), self.gateware_base()) { + let mut dst_oracle = + match BitstreamOracle::new( + old_key, + &pcache.fpga_key, + self.gateware(), + self.gateware_base()) { Ok(o) => o, Err(e) => { self.purge_password(PasswordType::Update); @@ -973,9 +1050,22 @@ impl<'a> RootKeys { return Err(e); } }; + + let next_progress = if provision_bbram { + pb.update_text(t!("rootkeys.init.backup_gateware", xous::LANG)); + pb.rebase_subtask_percentage(5, 30); + self.make_gateware_backup(Some(&mut pb), false)?; + 30 + } else { + 10 + }; log::debug!("destination oracle success"); - let keysource = dst_oracle.get_original_key_type(); - dst_oracle.set_target_key_type(keysource); + if provision_bbram { + dst_oracle.set_target_key_type(FpgaKeySource::Bbram); + } else { + let keysource = dst_oracle.get_original_key_type(); + dst_oracle.set_target_key_type(keysource); + } pb.set_percentage(6); // updates are always encrypted with the null key. let dummy_key: [u8; 32] = [0; 32]; @@ -991,9 +1081,12 @@ impl<'a> RootKeys { }; log::debug!("source oracle success"); - pb.set_percentage(10); + log::info!("source key type: {:?}", src_oracle.get_original_key_type()); + log::info!("destination key type: {:?}", dst_oracle.get_target_key_type()); + + pb.set_percentage(next_progress); pb.update_text(t!("rootkeys.init.patching_keys", xous::LANG)); - pb.rebase_subtask_percentage(10, 60); + pb.rebase_subtask_percentage(next_progress, 60); self.gateware_copy_and_patch(&src_oracle, &dst_oracle, Some(&mut pb))?; // make a copy of the plaintext metadata and csr records @@ -1018,10 +1111,16 @@ impl<'a> RootKeys { pb.set_percentage(92); // commit signatures - pb.update_text(t!("rootkeys.init.commit_signatures", xous::LANG)); - let (gateware_sig, gateware_len) = self.sign_gateware(&keypair); - log::debug!("gateware signature ({}): {:x?}", gateware_len, gateware_sig.to_bytes()); - self.commit_signature(gateware_sig, gateware_len, SignatureType::Gateware)?; + let keypair = if let Some(kp) = keypair { + pb.update_text(t!("rootkeys.init.commit_signatures", xous::LANG)); + let (gateware_sig, gateware_len) = self.sign_gateware(&kp); + log::debug!("gateware signature ({}): {:x?}", gateware_len, gateware_sig.to_bytes()); + self.commit_signature(gateware_sig, gateware_len, SignatureType::Gateware)?; + // pass the kp back into the original variable. keypair does not implement copy...for good reasons. + Some(kp) + } else { + None + }; // clean up the oracles pb.set_percentage(95); @@ -1032,16 +1131,36 @@ impl<'a> RootKeys { for b in keypair_bytes.iter_mut() { *b = 0; } + for b in old_key_storage.iter_mut() { + *b = 0; + } // ed25519 keypair zeroizes on drop // check signatures - pb.set_percentage(96); - if !self.verify_gateware_self_signature() { - return Err(RootkeyResult::IntegrityError); + if keypair.is_some() { + pb.set_percentage(96); + if !self.verify_gateware_self_signature() { + return Err(RootkeyResult::IntegrityError); + } } pb.set_percentage(100); + if provision_bbram { + self.ticktimer.sleep_ms(500).unwrap(); + // this will kick off the programming + log::info!("BURN_NOW"); + log::info!("{}", crate::CONSOLE_SENTINEL); + + // the key burning routine should finish before this timeout happens, and the system should have been rebooted + self.ticktimer.sleep_ms(10_000).unwrap(); + + pb.update_text(t!("rootkeys.bbram.failed_restore", xous::LANG)); + pb.set_percentage(0); + pb.rebase_subtask_percentage(0, 100); + self.make_gateware_backup(Some(&mut pb), true)?; + } + // check if we're to purge the password on completion if self.update_password_policy == PasswordRetentionPolicy::AlwaysPurge { self.purge_password(PasswordType::Update); @@ -1204,7 +1323,7 @@ impl<'a> RootKeys { // one time only /* - match self.make_gateware_backup(30, 50, progress_modal, progress_action) { + match self.make_gateware_backup(30, 50, progress_modal, progress_action, false) { Err(e) => { log::error!("got spinor error: {:?}", e); panic!("got spinor error, halting"); @@ -1513,13 +1632,10 @@ impl<'a> RootKeys { } - fn make_gateware_backup(&self, mut maybe_pb: Option<&mut ProgressBar>) -> Result<(), RootkeyResult> { - let gateware_dest = self.staging(); - let mut gateware_dest_base = self.staging_base(); - let gateware_src = self.gateware(); - - log::trace!("src: {:x?}", &gateware_src[0..32]); - log::trace!("dst: {:x?}", &gateware_dest[0..32]); + fn make_gateware_backup(&self, mut maybe_pb: Option<&mut ProgressBar>, do_restore: bool) -> Result<(), RootkeyResult> { + let gateware_dest = if !do_restore {self.staging()} else {self.gateware()}; + let mut gateware_dest_base = if !do_restore {self.staging_base()} else {self.gateware_base()}; + let gateware_src = if !do_restore {self.gateware()} else {self.staging()}; const PATCH_CHUNK: usize = 65536; // this controls the granularity of the erase operation let mut prog_ctr = 0; @@ -1541,8 +1657,6 @@ impl<'a> RootKeys { } } - log::trace!("src: {:x?}", &gateware_src[0..32]); - log::trace!("dst: {:x?}", &gateware_dest[0..32]); Ok(()) } diff --git a/services/root-keys/src/implementation/oracle.rs b/services/root-keys/src/implementation/oracle.rs index ca0fc6dc4..b14efb188 100644 --- a/services/root-keys/src/implementation/oracle.rs +++ b/services/root-keys/src/implementation/oracle.rs @@ -7,7 +7,7 @@ use aes_xous::{Aes256, NewBlockCipher, BlockDecrypt, BlockEncrypt}; use cipher::generic_array::GenericArray; #[derive(Debug, Copy, Clone)] -pub(crate) enum FpgaKeySource { +pub enum FpgaKeySource { Bbram, Efuse, } @@ -185,8 +185,7 @@ impl<'a> BitstreamOracle<'a> { self.ciphertext } pub fn get_original_key_type(&self) -> FpgaKeySource {self.dec_from_key} - /// the main use case for this API is changing from a BBRAM->eFuse source - /// we can't go eFuse->BBRAM because, unfortunately, we can't program BBRAM keys natively; the bitstream will have to have been constructed for BBRAM already for a good boot + pub fn get_target_key_type(&self) -> FpgaKeySource {self.enc_to_key} pub fn set_target_key_type(&mut self, keytype: FpgaKeySource) { self.enc_to_key = keytype; } diff --git a/services/root-keys/src/lib.rs b/services/root-keys/src/lib.rs index 1ee665c55..d6e8723e7 100644 --- a/services/root-keys/src/lib.rs +++ b/services/root-keys/src/lib.rs @@ -169,6 +169,12 @@ impl RootKeys { ).expect("couldn't send test message"); log::info!("test_ux response: {:?}", response); } + pub fn bbram_provision(&self) { + send_message(self.conn, + Message::new_scalar(Opcode::BbramProvision.to_usize().unwrap(), + 0, 0, 0, 0) + ).expect("couldn't send bbram provision message"); + } } use core::sync::atomic::{AtomicU32, Ordering}; @@ -202,7 +208,7 @@ impl BlockEncrypt for RootKeys { aes_op: AesOpType::Encrypt, }; let mut buf = Buffer::into_buf(op).unwrap(); - buf.lend_mut(self.conn, Opcode::AesOperation.to_u32().unwrap()).expect("couldn't initiate encrypt_block operation"); + buf.lend_mut(self.conn, Opcode::AesOracle.to_u32().unwrap()).expect("couldn't initiate encrypt_block operation"); let ret_op = buf.as_flat::().expect("got the wrong type of data structure back for encrypt_block"); if let ArchivedAesBlockType::SingleBlock(b) = ret_op.block { for (&src, dst) in b.iter().zip(block.as_mut_slice().iter_mut()) { @@ -226,7 +232,7 @@ impl BlockEncrypt for RootKeys { aes_op: AesOpType::Encrypt, }; let mut buf = Buffer::into_buf(op).unwrap(); - buf.lend_mut(self.conn, Opcode::AesOperation.to_u32().unwrap()).expect("couldn't initiate encrypt_block operation"); + buf.lend_mut(self.conn, Opcode::AesOracle.to_u32().unwrap()).expect("couldn't initiate encrypt_block operation"); let ret_op = buf.as_flat::().expect("got the wrong type of data structure back for encrypt_block"); if let ArchivedAesBlockType::ParBlock(pb) = ret_op.block { for (b, pbs) in pb.iter().zip(blocks.as_mut_slice().iter_mut()) { @@ -249,7 +255,7 @@ impl BlockDecrypt for RootKeys { aes_op: AesOpType::Decrypt, }; let mut buf = Buffer::into_buf(op).unwrap(); - buf.lend_mut(self.conn, Opcode::AesOperation.to_u32().unwrap()).expect("couldn't initiate encrypt_block operation"); + buf.lend_mut(self.conn, Opcode::AesOracle.to_u32().unwrap()).expect("couldn't initiate encrypt_block operation"); let ret_op = buf.as_flat::().expect("got the wrong type of data structure back for encrypt_block"); if let ArchivedAesBlockType::SingleBlock(b) = ret_op.block { for (&src, dst) in b.iter().zip(block.as_mut_slice().iter_mut()) { @@ -273,7 +279,7 @@ impl BlockDecrypt for RootKeys { aes_op: AesOpType::Decrypt, }; let mut buf = Buffer::into_buf(op).unwrap(); - buf.lend_mut(self.conn, Opcode::AesOperation.to_u32().unwrap()).expect("couldn't initiate encrypt_block operation"); + buf.lend_mut(self.conn, Opcode::AesOracle.to_u32().unwrap()).expect("couldn't initiate encrypt_block operation"); let ret_op = buf.as_flat::().expect("got the wrong type of data structure back for encrypt_block"); if let ArchivedAesBlockType::ParBlock(pb) = ret_op.block { for (b, pbs) in pb.iter().zip(blocks.as_mut_slice().iter_mut()) { diff --git a/services/root-keys/src/main.rs b/services/root-keys/src/main.rs index 7f6adc52e..f503152c5 100644 --- a/services/root-keys/src/main.rs +++ b/services/root-keys/src/main.rs @@ -19,6 +19,8 @@ use std::str; mod implementation; #[cfg(any(target_os = "none", target_os = "xous"))] use implementation::*; +/// used by the bbram helper/console protocol to indicate the start of a console message +const CONSOLE_SENTINEL: &'static str = "CONS_SENTINEL|"; #[cfg(any(target_os = "none", target_os = "xous"))] mod bcrypt; @@ -147,7 +149,7 @@ mod implementation { pub fn do_key_init(&mut self, rootkeys_modal: &mut Modal, main_cid: xous::CID) -> Result<(), RootkeyResult> { self.fake_progress(rootkeys_modal, main_cid, t!("rootkeys.setup_wait", xous::LANG)) } - pub fn do_gateware_update(&mut self, rootkeys_modal: &mut Modal, main_cid: xous::CID) -> Result<(), RootkeyResult> { + pub fn do_gateware_update(&mut self, rootkeys_modal: &mut Modal, main_cid: xous::CID, _provision_bbram: bool) -> Result<(), RootkeyResult> { self.fake_progress(rootkeys_modal, main_cid, t!("rootkeys.gwup_starting", xous::LANG)) } pub fn do_sign_xous(&mut self, rootkeys_modal: &mut Modal, main_cid: xous::CID) -> Result<(), RootkeyResult> { @@ -228,6 +230,7 @@ fn xmain() -> ! { log::trace!("registered with NS -- {:?}", keys_sid); let mut keys = RootKeys::new(); + log::info!("Boot FPGA key source: {:?}", keys.fpga_key_source()); // create the servers necessary to coordinate an auto-reboot sequence... let llio = llio::Llio::new(&xns).unwrap(); @@ -758,7 +761,7 @@ fn xmain() -> ! { } keys.set_ux_password_type(None); - let result = keys.do_gateware_update(&mut rootkeys_modal, main_cid); + let result = keys.do_gateware_update(&mut rootkeys_modal, main_cid, false); // 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}']); @@ -1002,7 +1005,7 @@ fn xmain() -> ! { panic!("entered a UxAesEnsureReturn but the flow was not set up correctly!") } } - Some(Opcode::AesOperation) => { + Some(Opcode::AesOracle) => { let mut buffer = unsafe { Buffer::from_memory_message_mut(msg.body.memory_message_mut().unwrap()) }; // as_flat saves a copy step, but we have to deserialize some enums manually let mut aes_op = buffer.to_original::().unwrap(); @@ -1027,6 +1030,125 @@ fn xmain() -> ! { buffer.replace(aes_op).unwrap(); }, + Some(Opcode::BbramProvision) => { + dismiss_modal_action.set_action_opcode(Opcode::UxBbramCheckHelper.to_u32().unwrap()); + rootkeys_modal.modify( + Some(ActionType::Notification(dismiss_modal_action)), + Some(t!("rootkeys.bbram.confirm", xous::LANG)), false, + None, false, None); + rootkeys_modal.activate(); + } + Some(Opcode::UxBbramCheckHelper) => { + let console_input = gam::modal::ConsoleInput::new( + main_cid, + Opcode::UxBbramCheckReturn.to_u32().unwrap() + ); + rootkeys_modal.modify( + Some(ActionType::ConsoleInput(console_input)), + Some(t!("rootkeys.console_input", xous::LANG)), false, + None, true, None); + rootkeys_modal.activate(); + log::info!("{}check_conn", CONSOLE_SENTINEL); + } + Some(Opcode::UxBbramCheckReturn) => { + let buf = unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) }; + let console_text = buf.to_original::().unwrap(); + log::info!("got console text:{}", console_text.as_str()); + if console_text.as_str().starts_with("HELPER_OK") { + log::info!("got '{}', moving on", console_text.as_str()); + // proceed + if keys.is_pcache_update_password_valid() || !keys.is_initialized() { + send_message(main_cid, + xous::Message::new_scalar(Opcode::UxBbramRun.to_usize().unwrap(), 0, 0, 0, 0) + ).unwrap(); + } else { + keys.set_ux_password_type(Some(PasswordType::Update)); + password_action.set_action_opcode(Opcode::UxBbramPasswordReturn.to_u32().unwrap()); + rootkeys_modal.modify( + Some(ActionType::TextEntry(password_action)), + Some(t!("rootkeys.get_signing_password", xous::LANG)), false, + None, true, None + ); + rootkeys_modal.activate(); + } + } else { + // abort with help message + dismiss_modal_action.set_action_opcode(Opcode::UxGutter.to_u32().unwrap()); + rootkeys_modal.modify( + Some(ActionType::Notification(dismiss_modal_action)), + Some(t!("rootkeys.bbram.no_helper", xous::LANG)), false, + None, false, None); + rootkeys_modal.activate(); + } + } + Some(Opcode::UxBbramPasswordReturn) => { + let mut buf = unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) }; + let mut plaintext_pw = buf.to_original::().unwrap(); + + keys.hash_and_save_password(plaintext_pw.as_str()); + plaintext_pw.volatile_clear(); // ensure the data is destroyed after sending to the keys enclave + buf.volatile_clear(); + send_message(main_cid, + xous::Message::new_scalar(Opcode::UxBbramRun.to_usize().unwrap(), 0, 0, 0, 0) + ).unwrap(); + } + Some(Opcode::UxBbramRun) => { + keys.set_ux_password_type(None); + let result = keys.do_gateware_update(&mut rootkeys_modal, main_cid, true); + // 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(_) => { + dismiss_modal_action.set_action_opcode(Opcode::UxGutter.to_u32().unwrap()); + rootkeys_modal.modify( + Some(ActionType::Notification(dismiss_modal_action)), + Some(t!("rootkeys.bbram.finished", xous::LANG)), false, + None, false, None); + rootkeys_modal.activate(); + xous::yield_slice(); + } + Err(RootkeyResult::AlignmentError) => { + dismiss_modal_action.set_action_opcode(Opcode::UxGutter.to_u32().unwrap()); + rootkeys_modal.modify( + Some(ActionType::Notification(dismiss_modal_action)), + Some(t!("rootkeys.init.fail_alignment", xous::LANG)), false, + None, false, None); + rootkeys_modal.activate(); + xous::yield_slice(); + } + Err(RootkeyResult::KeyError) => { + // probably a bad password, purge it, so the user can try again + keys.purge_password(PasswordType::Update); + dismiss_modal_action.set_action_opcode(Opcode::UxGutter.to_u32().unwrap()); + rootkeys_modal.modify( + Some(ActionType::Notification(dismiss_modal_action)), + Some(t!("rootkeys.init.fail_key", xous::LANG)), false, + None, false, None); + rootkeys_modal.activate(); + xous::yield_slice(); + } + Err(RootkeyResult::IntegrityError) => { + dismiss_modal_action.set_action_opcode(Opcode::UxGutter.to_u32().unwrap()); + rootkeys_modal.modify( + Some(ActionType::Notification(dismiss_modal_action)), + Some(t!("rootkeys.init.fail_verify", xous::LANG)), false, + None, false, None); + rootkeys_modal.activate(); + xous::yield_slice(); + } + Err(RootkeyResult::FlashError) => { + dismiss_modal_action.set_action_opcode(Opcode::UxGutter.to_u32().unwrap()); + rootkeys_modal.modify( + Some(ActionType::Notification(dismiss_modal_action)), + Some(t!("rootkeys.init.fail_burn", xous::LANG)), false, + None, false, None); + rootkeys_modal.activate(); + xous::yield_slice(); + } + } + } + Some(Opcode::CheckGatewareSignature) => msg_blocking_scalar_unpack!(msg, _, _, _, _, { if keys.is_initialized() { if keys.verify_gateware_self_signature() { diff --git a/services/shellchat/src/cmds/keys.rs b/services/shellchat/src/cmds/keys.rs index eb4f5d413..19704688a 100644 --- a/services/shellchat/src/cmds/keys.rs +++ b/services/shellchat/src/cmds/keys.rs @@ -56,6 +56,10 @@ impl<'a> ShellCmdApi<'a> for Keys { //debug_here::debug_here!(); write!(ret, "show UX").unwrap(); } + "bbram" => { + self.rootkeys.bbram_provision(); + write!(ret, "Provisioning BBRAM").unwrap(); + } "aes" => { use aes_xous::{BlockEncrypt, BlockDecrypt}; let mut pass = true;