mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-03 20:13:48 +00:00
SECURITY: fix timing variability in backend/serial/u32/scalar.rs (#661)
Similar security fix to #659, but for the 32-bit backend. See that PR for more information about the problem. Relevant compiler outputs (thanks to @tarcieri): Without fix https://godbolt.org/z/zvaWxzvqv Notice the `jns` ("jump if not sign") instruction on line 106. With fix https://godbolt.org/z/jc9j7eb8E
This commit is contained in:
parent
415892acf1
commit
b4f9e4df92
1 changed files with 9 additions and 1 deletions
|
|
@ -185,6 +185,14 @@ impl Scalar29 {
|
|||
|
||||
/// Compute `a - b` (mod l).
|
||||
pub fn sub(a: &Scalar29, b: &Scalar29) -> Scalar29 {
|
||||
// Optimization barrier to prevent compiler from inserting branch instructions
|
||||
// TODO(tarcieri): find a better home (or abstraction) for this
|
||||
fn black_box(value: u32) -> u32 {
|
||||
// SAFETY: `u32` is a simple integer `Copy` type and `value` lives on the stack so
|
||||
// a pointer to it will be valid.
|
||||
unsafe { core::ptr::read_volatile(&value) }
|
||||
}
|
||||
|
||||
let mut difference = Scalar29::ZERO;
|
||||
let mask = (1u32 << 29) - 1;
|
||||
|
||||
|
|
@ -199,7 +207,7 @@ impl Scalar29 {
|
|||
let underflow_mask = ((borrow >> 31) ^ 1).wrapping_sub(1);
|
||||
let mut carry: u32 = 0;
|
||||
for i in 0..9 {
|
||||
carry = (carry >> 29) + difference[i] + (constants::L[i] & underflow_mask);
|
||||
carry = (carry >> 29) + difference[i] + (constants::L[i] & black_box(underflow_mask));
|
||||
difference[i] = carry & mask;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue