diff --git a/curve25519-dalek/src/backend/serial/u32e/field.rs b/curve25519-dalek/src/backend/serial/u32e/field.rs index 3a895ea..e7153ac 100644 --- a/curve25519-dalek/src/backend/serial/u32e/field.rs +++ b/curve25519-dalek/src/backend/serial/u32e/field.rs @@ -129,69 +129,76 @@ pub(crate) fn engine(a: &[u8; 32], b: &[u8; 32], op: EngineOp) -> Engine25519 { ) }, ]; - - match op { - EngineOp::Mul => { - let prog = assemble_engine25519!( + loop { + let prog_len = match op { + EngineOp::Mul => { + 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: - mul %2, %0, %1 + add %2, %0, %1 + trd %30, %2 + sub %2, %2, %30 fin - ); - for (&src, dest) in prog.iter().zip(mcode.iter_mut()) { - *dest = src; + ); + for (&src, dest) in prog.iter().zip(mcode.iter_mut()) { + *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::Add => { - let prog = assemble_engine25519!( - start: - add %2, %0, %1 - trd %30, %2 - sub %2, %2, %30 - fin - ); - for (&src, dest) in prog.iter().zip(mcode.iter_mut()) { - *dest = src; + EngineOp::Sub => { + let prog = assemble_engine25519!( + start: + sub %1, #3, %1 + 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); + prog.len() } - engine.wfo(utra::engine::MPLEN_MPLEN, prog.len() as u32); - } - EngineOp::Sub => { - let prog = assemble_engine25519!( - start: - sub %1, #3, %1 - add %2, %0, %1 - trd %30, %2 - sub %2, %2, %30 - fin - ); - for (&src, dest) in prog.iter().zip(mcode.iter_mut()) { - *dest = src; + }; + // 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)); } - 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 - 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]]; - unsafe { - (dst as *mut u32).write_volatile(u32::from_le_bytes(bytes)); + // copy b arg + 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]]; + unsafe { + (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 let mut result: [u8; 32] = [0; 32]; for (&src, dst) in rf[2].iter().zip(result.chunks_exact_mut(4)) { diff --git a/curve25519-dalek/src/montgomery.rs b/curve25519-dalek/src/montgomery.rs index f94c9f4..da618fa 100644 --- a/curve25519-dalek/src/montgomery.rs +++ b/curve25519-dalek/src/montgomery.rs @@ -468,10 +468,16 @@ impl ProjectivePoint { let mut ucode_hw = unsafe { get_ucode() }; let rf_hw = unsafe { get_rf() }; - copy_to_rf(self.U.as_bytes(), 29, rf_hw, 0); - copy_to_rf(self.W.as_bytes(), 30, rf_hw, 0); + let mut r; + 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")] free_engine(); r @@ -637,19 +643,24 @@ pub(crate) fn differential_add_and_double( let mut ucode_hw = unsafe { get_ucode() }; let rf_hw = unsafe { get_rf() }; - // P.U in %20 - // P.W in %21 - // Q.U in %22 - // Q.W in %23 - // affine_PmQ in %24 - copy_to_rf(P.U.as_bytes(), 20, rf_hw, 0); - copy_to_rf(P.W.as_bytes(), 21, rf_hw, 0); - copy_to_rf(Q.U.as_bytes(), 22, 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); + loop { + // P.U in %20 + // P.W in %21 + // Q.U in %22 + // Q.W in %23 + // affine_PmQ in %24 + copy_to_rf(P.U.as_bytes(), 20, rf_hw, 0); + copy_to_rf(P.W.as_bytes(), 21, rf_hw, 0); + copy_to_rf(Q.U.as_bytes(), 22, 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 - run_job(&mut ucode_hw, &rf_hw, &mcode, 0); + // start the run + run_job(&mut ucode_hw, &rf_hw, &mcode, 0); + if !was_engine_error(mcode.len()) { + break; + } + } P.U = FieldElement::from_bytes(©_from_rf(20, &rf_hw, 0)); P.W = FieldElement::from_bytes(©_from_rf(21, &rf_hw, 0)); @@ -998,28 +1009,34 @@ impl Mul<&Scalar> for &MontgomeryPoint { let window = 0; match ensure_engine() { Ok(_) => { - // safety: these were called after ensure_engine() - let mut ucode_hw = unsafe { get_ucode() }; - let mut rf_hw = unsafe { get_rf() }; + let mut r; + loop { + // 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.W.as_bytes(), 26, &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(affine_u.as_bytes(), 24, &mut rf_hw, window); - copy_to_rf(scalar.bytes, 31, &mut rf_hw, window); - copy_to_rf( - [ - 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, - ], - 19, - &mut rf_hw, - window, - ); // 254 as loop counter + 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(x1.U.as_bytes(), 27, &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(scalar.bytes, 31, &mut rf_hw, window); + copy_to_rf( + [ + 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, + ], + 19, + &mut rf_hw, + window, + ); // 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")] free_engine(); r