Skip to content

Commit dac6f1b

Browse files
committed
SECURITY: fix timing variability in backend/serial/u32/scalar.rs
Similar security fix to #659, but for the 32-bit backend. See that PR for more information about the problem.
1 parent 415892a commit dac6f1b

File tree

1 file changed

+9
-1
lines changed
  • curve25519-dalek/src/backend/serial/u32

1 file changed

+9
-1
lines changed

curve25519-dalek/src/backend/serial/u32/scalar.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@ impl Scalar29 {
185185

186186
/// Compute `a - b` (mod l).
187187
pub fn sub(a: &Scalar29, b: &Scalar29) -> Scalar29 {
188+
// Optimization barrier to prevent compiler from inserting branch instructions
189+
// TODO(tarcieri): find a better home (or abstraction) for this
190+
fn black_box(value: u32) -> u32 {
191+
// SAFETY: `u32` is a simple integer `Copy` type and `value` lives on the stack so
192+
// a pointer to it will be valid.
193+
unsafe { core::ptr::read_volatile(&value) }
194+
}
195+
188196
let mut difference = Scalar29::ZERO;
189197
let mask = (1u32 << 29) - 1;
190198

@@ -199,7 +207,7 @@ impl Scalar29 {
199207
let underflow_mask = ((borrow >> 31) ^ 1).wrapping_sub(1);
200208
let mut carry: u32 = 0;
201209
for i in 0..9 {
202-
carry = (carry >> 29) + difference[i] + (constants::L[i] & underflow_mask);
210+
carry = (carry >> 29) + difference[i] + (constants::L[i] & black_box(underflow_mask));
203211
difference[i] = carry & mask;
204212
}
205213

0 commit comments

Comments
 (0)