diff options
| author | Daniel Schadt <kingdread@gmx.de> | 2025-04-09 21:24:53 +0200 | 
|---|---|---|
| committer | Daniel Schadt <kingdread@gmx.de> | 2025-04-09 21:24:53 +0200 | 
| commit | 098e7d6aacbd1d496816ce0291a981ff665b2a36 (patch) | |
| tree | 28765992d56665dc98988b8d2e5ab70fad325e0f | |
| parent | 364e19dc96d97c0b38eeb389054e9d990ae47f11 (diff) | |
| download | zears-098e7d6aacbd1d496816ce0291a981ff665b2a36.tar.gz zears-098e7d6aacbd1d496816ce0291a981ff665b2a36.tar.bz2 zears-098e7d6aacbd1d496816ce0291a981ff665b2a36.zip | |
change aez_prf to write into a buffer
| -rw-r--r-- | src/lib.rs | 37 | 
1 files changed, 22 insertions, 15 deletions
| @@ -315,7 +315,9 @@ fn encrypt(key: &Key, nonce: &[u8], ad: &[&[u8]], tau: u32, buffer: &mut [u8]) {      tweaks.extend(ad);      assert!(buffer.len() >= tau as usize);      if buffer.len() == tau as usize { -        buffer.copy_from_slice(&aez_prf(key, &tweaks, tau)); +        // As aez_prf only xor's the input in, we have to clear the buffer first +        buffer.fill(0); +        aez_prf(key, &tweaks, buffer);      } else {          encipher(key, &tweaks, buffer);      } @@ -337,7 +339,8 @@ fn decrypt<'a>(      tweaks.extend(ad);      if ciphertext.len() == tau as usize { -        if constant_time_eq(&ciphertext, &aez_prf(key, &tweaks, tau)) { +        aez_prf(key, &tweaks, ciphertext); +        if is_zeroes(&ciphertext) {              return Some(&[]);          } else {              return None; @@ -347,16 +350,19 @@ fn decrypt<'a>(      decipher(key, &tweaks, ciphertext);      let (m, auth) = ciphertext.split_at(ciphertext.len() - tau as usize);      assert!(auth.len() == tau as usize); -    let comparator = if tau as usize <= ZEROES.len() { -        &ZEROES[..tau as usize] + +    if is_zeroes(&auth) { Some(m) } else { None } +} + +fn is_zeroes(data: &[u8]) -> bool { +    let comparator = if data.len() <= ZEROES.len() { +        &ZEROES[..data.len()]      } else { -        &vec![0; tau as usize] +        // We should find a way to do this without allocating a separate buffer full of zeroes, but +        // I don't want to hand-roll my constant-time-is-zeroes yet. +        &vec![0; data.len()]      }; -    if constant_time_eq(&auth, comparator) { -        Some(m) -    } else { -        None -    } +    constant_time_eq(data, comparator)  }  fn encipher(key: &Key, tweaks: Tweak, message: &mut [u8]) { @@ -702,16 +708,17 @@ fn aez_hash(key: &Key, tweaks: Tweak) -> Block {      hash  } -fn aez_prf(key: &Key, tweaks: Tweak, tau: u32) -> Vec<u8> { -    let mut result = Vec::new(); +/// XOR's the result of aez_prf into the given buffer +fn aez_prf(key: &Key, tweaks: Tweak, buffer: &mut [u8]) {      let mut index = 0u128;      let delta = aez_hash(key, tweaks); -    while result.len() < tau as usize { +    for chunk in buffer.chunks_mut(16) {          let block = e(-1, 3, key, delta ^ Block::from_int(index)); -        result.extend_from_slice(&block.0[..16.min(tau as usize - result.len())]); +        for (a, b) in chunk.iter_mut().zip(block.0.iter()) { +            *a ^= b; +        }          index += 1;      } -    result  }  /// Represents a computation of E_K^{j,i}. | 
