add handlers to check for hardware errors and try to recover

This commit is contained in:
bunnie 2024-03-28 10:20:53 +08:00
parent c0d9b40d9d
commit 4170979f6a
2 changed files with 112 additions and 88 deletions

View file

@ -129,69 +129,76 @@ pub(crate) fn engine(a: &[u8; 32], b: &[u8; 32], op: EngineOp) -> Engine25519 {
) )
}, },
]; ];
loop {
match op { let prog_len = match op {
EngineOp::Mul => { EngineOp::Mul => {
let prog = assemble_engine25519!( let prog = assemble_engine25519!(
start:
mul %2, %0, %1
fin
);
for (&src, dest) in prog.iter().zip(mcode.iter_mut()) {
*dest = src;
}
engine.wfo(utra::engine::MPLEN_MPLEN, prog.len() as u32);
prog.len()
}
EngineOp::Add => {
let prog = assemble_engine25519!(
start: start:
mul %2, %0, %1 add %2, %0, %1
trd %30, %2
sub %2, %2, %30
fin fin
); );
for (&src, dest) in prog.iter().zip(mcode.iter_mut()) { for (&src, dest) in prog.iter().zip(mcode.iter_mut()) {
*dest = src; *dest = src;
}
engine.wfo(utra::engine::MPLEN_MPLEN, prog.len() as u32);
prog.len()
} }
engine.wfo(utra::engine::MPLEN_MPLEN, prog.len() as u32); EngineOp::Sub => {
} let prog = assemble_engine25519!(
EngineOp::Add => { start:
let prog = assemble_engine25519!( sub %1, #3, %1
start: add %2, %0, %1
add %2, %0, %1 trd %30, %2
trd %30, %2 sub %2, %2, %30
sub %2, %2, %30 fin
fin );
); for (&src, dest) in prog.iter().zip(mcode.iter_mut()) {
for (&src, dest) in prog.iter().zip(mcode.iter_mut()) { *dest = src;
*dest = src; }
engine.wfo(utra::engine::MPLEN_MPLEN, prog.len() as u32);
prog.len()
} }
engine.wfo(utra::engine::MPLEN_MPLEN, prog.len() as u32); };
} // copy a arg
EngineOp::Sub => { for (src, dst) in a.chunks_exact(4).zip(rf[0].iter_mut()) {
let prog = assemble_engine25519!( let bytes: [u8; 4] = [src[0], src[1], src[2], src[3]];
start: unsafe {
sub %1, #3, %1 (dst as *mut u32).write_volatile(u32::from_le_bytes(bytes));
add %2, %0, %1
trd %30, %2
sub %2, %2, %30
fin
);
for (&src, dest) in prog.iter().zip(mcode.iter_mut()) {
*dest = src;
} }
engine.wfo(utra::engine::MPLEN_MPLEN, prog.len() as u32); /* this is a bad idea: src[0..4].try_into().unwrap()
because "unwrap()" adds in a whole bunch of string formatting stuff, adds +16k or so to the binary size
*/
} }
}
// copy a arg
for (src, dst) in a.chunks_exact(4).zip(rf[0].iter_mut()) {
let bytes: [u8; 4] = [src[0], src[1], src[2], src[3]];
unsafe {
(dst as *mut u32).write_volatile(u32::from_le_bytes(bytes));
}
/* this is a bad idea: src[0..4].try_into().unwrap()
because "unwrap()" adds in a whole bunch of string formatting stuff, adds +16k or so to the binary size
*/
}
// copy b arg // copy b arg
for (src, dst) in b.chunks_exact(4).zip(rf[1].iter_mut()) { for (src, dst) in b.chunks_exact(4).zip(rf[1].iter_mut()) {
let bytes: [u8; 4] = [src[0], src[1], src[2], src[3]]; let bytes: [u8; 4] = [src[0], src[1], src[2], src[3]];
unsafe { unsafe {
(dst as *mut u32).write_volatile(u32::from_le_bytes(bytes)); (dst as *mut u32).write_volatile(u32::from_le_bytes(bytes));
}
}
engine.wfo(utra::engine::CONTROL_GO, 1);
while engine.rf(utra::engine::STATUS_RUNNING) != 0 {}
if !was_engine_error(prog_len) {
break;
} }
} }
engine.wfo(utra::engine::CONTROL_GO, 1);
while engine.rf(utra::engine::STATUS_RUNNING) != 0 {}
// return result, always in reg 2 // return result, always in reg 2
let mut result: [u8; 32] = [0; 32]; let mut result: [u8; 32] = [0; 32];
for (&src, dst) in rf[2].iter().zip(result.chunks_exact_mut(4)) { for (&src, dst) in rf[2].iter().zip(result.chunks_exact_mut(4)) {

View file

@ -468,10 +468,16 @@ impl ProjectivePoint {
let mut ucode_hw = unsafe { get_ucode() }; let mut ucode_hw = unsafe { get_ucode() };
let rf_hw = unsafe { get_rf() }; let rf_hw = unsafe { get_rf() };
copy_to_rf(self.U.as_bytes(), 29, rf_hw, 0); let mut r;
copy_to_rf(self.W.as_bytes(), 30, rf_hw, 0); loop {
copy_to_rf(self.U.as_bytes(), 29, rf_hw, 0);
copy_to_rf(self.W.as_bytes(), 30, rf_hw, 0);
let r = MontgomeryPoint(run_job(&mut ucode_hw, &rf_hw, &mcode, 0)); r = MontgomeryPoint(run_job(&mut ucode_hw, &rf_hw, &mcode, 0));
if !was_engine_error(mcode.len()) {
break;
}
}
#[cfg(feature="auto-release")] #[cfg(feature="auto-release")]
free_engine(); free_engine();
r r
@ -637,19 +643,24 @@ pub(crate) fn differential_add_and_double(
let mut ucode_hw = unsafe { get_ucode() }; let mut ucode_hw = unsafe { get_ucode() };
let rf_hw = unsafe { get_rf() }; let rf_hw = unsafe { get_rf() };
// P.U in %20 loop {
// P.W in %21 // P.U in %20
// Q.U in %22 // P.W in %21
// Q.W in %23 // Q.U in %22
// affine_PmQ in %24 // Q.W in %23
copy_to_rf(P.U.as_bytes(), 20, rf_hw, 0); // affine_PmQ in %24
copy_to_rf(P.W.as_bytes(), 21, rf_hw, 0); copy_to_rf(P.U.as_bytes(), 20, rf_hw, 0);
copy_to_rf(Q.U.as_bytes(), 22, rf_hw, 0); copy_to_rf(P.W.as_bytes(), 21, rf_hw, 0);
copy_to_rf(Q.W.as_bytes(), 23, rf_hw, 0); copy_to_rf(Q.U.as_bytes(), 22, rf_hw, 0);
copy_to_rf(affine_PmQ.as_bytes(), 24, rf_hw, 0); copy_to_rf(Q.W.as_bytes(), 23, rf_hw, 0);
copy_to_rf(affine_PmQ.as_bytes(), 24, rf_hw, 0);
// start the run // start the run
run_job(&mut ucode_hw, &rf_hw, &mcode, 0); run_job(&mut ucode_hw, &rf_hw, &mcode, 0);
if !was_engine_error(mcode.len()) {
break;
}
}
P.U = FieldElement::from_bytes(&copy_from_rf(20, &rf_hw, 0)); P.U = FieldElement::from_bytes(&copy_from_rf(20, &rf_hw, 0));
P.W = FieldElement::from_bytes(&copy_from_rf(21, &rf_hw, 0)); P.W = FieldElement::from_bytes(&copy_from_rf(21, &rf_hw, 0));
@ -998,28 +1009,34 @@ impl Mul<&Scalar> for &MontgomeryPoint {
let window = 0; let window = 0;
match ensure_engine() { match ensure_engine() {
Ok(_) => { Ok(_) => {
// safety: these were called after ensure_engine() let mut r;
let mut ucode_hw = unsafe { get_ucode() }; loop {
let mut rf_hw = unsafe { get_rf() }; // safety: these were called after ensure_engine()
let mut ucode_hw = unsafe { get_ucode() };
let mut rf_hw = unsafe { get_rf() };
copy_to_rf(x0.U.as_bytes(), 25, &mut rf_hw, window); copy_to_rf(x0.U.as_bytes(), 25, &mut rf_hw, window);
copy_to_rf(x0.W.as_bytes(), 26, &mut rf_hw, window); copy_to_rf(x0.W.as_bytes(), 26, &mut rf_hw, window);
copy_to_rf(x1.U.as_bytes(), 27, &mut rf_hw, window); copy_to_rf(x1.U.as_bytes(), 27, &mut rf_hw, window);
copy_to_rf(x1.W.as_bytes(), 28, &mut rf_hw, window); copy_to_rf(x1.W.as_bytes(), 28, &mut rf_hw, window);
copy_to_rf(affine_u.as_bytes(), 24, &mut rf_hw, window); copy_to_rf(affine_u.as_bytes(), 24, &mut rf_hw, window);
copy_to_rf(scalar.bytes, 31, &mut rf_hw, window); copy_to_rf(scalar.bytes, 31, &mut rf_hw, window);
copy_to_rf( copy_to_rf(
[ [
254, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 254, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
], ],
19, 19,
&mut rf_hw, &mut rf_hw,
window, window,
); // 254 as loop counter ); // 254 as loop counter
let r = MontgomeryPoint(run_job(&mut ucode_hw, &rf_hw, &mcode, window)); r = MontgomeryPoint(run_job(&mut ucode_hw, &rf_hw, &mcode, window));
if !was_engine_error(mcode.len()) {
break;
}
}
#[cfg(feature="auto-release")] #[cfg(feature="auto-release")]
free_engine(); free_engine();
r r