···11-use subtle::{Choice, ConstantTimeEq};
11+use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess};
2233use crate::{
44 GarbledError, STROBE_VERSION,
···162162 fn increment_position(&mut self, increment: usize) {
163163 self.position += increment;
164164165165- if self.position == self.rate {
165165+ if self.position.ct_eq(&self.rate).into() {
166166 self.permutation_f();
167167 }
168168 }
···240240 /// input, and like `overwrite` in that we do not mutate (or take) any input.
241241 fn zero_state(&mut self, mut bytes_to_zero: usize) {
242242 // Do the zero-writing in chunks
243243- while bytes_to_zero > 0 {
244244- let slice_len = core::cmp::min(self.rate - self.position, bytes_to_zero);
243243+ while bytes_to_zero.ct_ne(&0).into() {
244244+ let min_slice = (self.rate - self.position) as u32;
245245+ let to_zero = bytes_to_zero as u32;
246246+247247+ let slice_len = ConditionallySelectable::conditional_select(
248248+ &min_slice,
249249+ &to_zero,
250250+ to_zero.ct_lt(&min_slice),
251251+ ) as usize;
245252246253 self.state.0[self.position..(self.position + slice_len)].fill(0);
247254···282289 /// Performs the state / data transformation that corresponds to the given flags. If `more` is
283290 /// given, this will treat `data` as a continuation of the data given in the previous
284291 /// call to `operate`.
285285- fn operate(&mut self, flags: OpFlags, data: &mut [u8], more: Choice) {
292292+ fn operate(&mut self, mut flags: OpFlags, data: &mut [u8], more: Choice) {
286293 self.prev_flags = flags;
287294288295 // If `more` isn't set, this is a new operation. Do the begin_op sequence
···291298 }
292299293300 // Meta-ness is only relevant for `begin_op`. Remove it to simplify the below logic.
294294- let flags = flags & !OpFlags::META;
301301+ flags &= !OpFlags::META;
295302296303 // Flags that don't pass this assertion should normally call `absorb`, but `absorb` does not mutate,
297304 // so the implementor should have used operate_no_mutate instead
···309316 /// Performs the state transformation that corresponds to the given flags. If `more` is given,
310317 /// this will treat `data` as a continuation of the data given in the previous call to
311318 /// `operate`. This uses non-mutating variants of the specializations of the `duplex` function.
312312- fn operate_no_mutate(&mut self, flags: OpFlags, data: &[u8], more: Choice) {
319319+ fn operate_no_mutate(&mut self, mut flags: OpFlags, data: &[u8], more: Choice) {
313320 self.prev_flags = flags;
314321315322 // If `more` isn't set, this is a new operation. Do the begin_op sequence
···318325 }
319326320327 // Meta-ness is only relevant for `begin_op`. Remove it to simplify the below logic.
321321- let flags = flags & !OpFlags::META;
328328+ flags &= !OpFlags::META;
322329323330 // Flags that trigger the assertion to fail are mutating operations.
324331 // RATCHET is special cased to never call operate/operate_no_mutate directly
325325- debug_assert!(
326326- flags != ops::PRF && !bool::from(flags.contains(OpFlags::CIPHER | OpFlags::TRANSPORT))
327327- || bool::from(flags.contains(OpFlags::INBOUND))
328328- );
332332+ debug_assert!(flags == ops::KEY || !bool::from(flags.contains(OpFlags::CIPHER)));
329333330334 // There are no non-mutating variants of things with flags & (C | T | I) == C | T
331335 if flags.contains(OpFlags::CIPHER).into() {
···339343 }
340344 }
341345342342- fn recv_mac_inner(&mut self, mac_copy: &mut [u8], flags: OpFlags) -> Result<(), GarbledError> {
346346+ fn recv_mac_inner(&mut self, flags: OpFlags, mac_copy: &mut [u8]) -> Result<(), GarbledError> {
343347 // recv_mac can never be streamed
344348 self.operate(flags, mac_copy, Choice::from(0u8));
345349···355359 pub fn recv_mac<const N: usize>(&mut self, mac: &[u8; N]) -> Result<(), GarbledError> {
356360 let mut mac_copy = *mac;
357361358358- self.recv_mac_inner(&mut mac_copy, ops::RECV_MAC)
362362+ self.recv_mac_inner(ops::RECV_MAC, &mut mac_copy)
359363 }
360364361365 pub fn meta_recv_mac<const N: usize>(&mut self, mac: &[u8; N]) -> Result<(), GarbledError> {
362366 let mut mac_copy = *mac;
363367364364- self.recv_mac_inner(&mut mac_copy, ops::META_RECV_MAC)
368368+ self.recv_mac_inner(ops::META_RECV_MAC, &mut mac_copy)
365369 }
366370367367- fn ratchet_inner(&mut self, num_bytes_to_zero: usize, flags: OpFlags) {
368368- let more = self.prev_flags.bits().ct_eq(&flags.bits());
371371+ fn ratchet_inner(&mut self, mut flags: OpFlags, num_bytes_to_zero: usize) {
372372+ let more = self.prev_flags.ct_eq(&flags);
369373370374 // We don't make an `operate` call, since this is a super special case. That means we have
371375 // to make the `begin_op` call manually.
···375379 self.begin_op(flags);
376380 }
377381382382+ flags &= !OpFlags::META;
383383+378384 self.zero_state(num_bytes_to_zero);
379385 }
380386381387 pub fn ratchet(&mut self, num_bytes_to_zero: usize) {
382382- self.ratchet_inner(num_bytes_to_zero, ops::RATCHET);
388388+ self.ratchet_inner(ops::RATCHET, num_bytes_to_zero);
383389 }
384390385391 pub fn meta_ratchet(&mut self, num_bytes_to_zero: usize) {
386386- self.ratchet_inner(num_bytes_to_zero, ops::META_RATCHET);
392392+ self.ratchet_inner(ops::META_RATCHET, num_bytes_to_zero);
387393 }
388394389395 define_mut_operations! {