mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
add bbram provisioning sequence
This commit is contained in:
parent
2c6abd627d
commit
c3fc3ff23f
12 changed files with 518 additions and 194 deletions
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<device schemaVersion="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd" >
|
||||
<vendor>litex</vendor>
|
||||
<name>SOC</name>
|
||||
<description><![CDATA[Litex SoC 2021-08-14 19:53:02]]></description>
|
||||
<description><![CDATA[Litex SoC 2021-08-19 00:43:18]]></description>
|
||||
|
||||
<addressUnitBits>8</addressUnitBits>
|
||||
<width>32</width>
|
||||
|
|
@ -3584,7 +3584,7 @@ inject too fast.]]></description>
|
|||
<name>SEED1</name>
|
||||
<description><![CDATA[Bits 32-63 of `SEED_SEED`. Seed used for the build]]></description>
|
||||
<addressOffset>0x0000</addressOffset>
|
||||
<resetValue>0x356326ec</resetValue>
|
||||
<resetValue>0x1e0a17d9</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
@ -3599,7 +3599,7 @@ inject too fast.]]></description>
|
|||
<name>SEED0</name>
|
||||
<description><![CDATA[Bits 0-31 of `SEED_SEED`.]]></description>
|
||||
<addressOffset>0x0004</addressOffset>
|
||||
<resetValue>0x6d0d21ea</resetValue>
|
||||
<resetValue>0x7f08f543</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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<xous_ipc::String::<512>>, 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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安全含义:至关重要 ",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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::<u32>()[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::<u32>()[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::<u32>()[KeyRomLocs::FPGA_KEY as usize..KeyRomLocs::FPGA_KEY as usize + 256/(size_of::<u32>()*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::<u32>()[KeyRomLocs::FPGA_KEY as usize..KeyRomLocs::FPGA_KEY as usize + 256/(size_of::<u32>()*8)].iter_mut()
|
||||
for (word, hashed_pass) in self.sensitive_data.borrow_mut().as_slice_mut::<u32>()[KeyRomLocs::FPGA_KEY as usize..KeyRomLocs::FPGA_KEY as usize + 256/(size_of::<u32>()*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<Keypair> = 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(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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::<AesOp, _>().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::<AesOp, _>().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::<AesOp, _>().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::<AesOp, _>().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()) {
|
||||
|
|
|
|||
|
|
@ -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::<AesOp, _>().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::<gam::modal::TextEntryPayload, _>().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::<gam::modal::TextEntryPayload, _>().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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue