Skip to content

Commit c24ba7c

Browse files
committed
ssh-cipher: simply Poly1305 MAC computation
Uses slightly simpler logic with fewer branches/special cases, and adds more explanatory comments
1 parent 10acc1b commit c24ba7c

1 file changed

Lines changed: 25 additions & 19 deletions

File tree

ssh-cipher/src/chacha20poly1305.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,26 +135,32 @@ impl Cipher {
135135

136136
/// Compute the MAC for a given input buffer (containing ciphertext).
137137
fn compute_mac(mut mac: Poly1305, aad: &[u8], buffer: &[u8]) -> Result<Tag> {
138-
match aad.len() {
139-
0 => Ok(mac.compute_unpadded(buffer)),
140-
1..=poly1305::BLOCK_SIZE => {
141-
let mut block = poly1305::Block::default();
142-
block[..aad.len()].copy_from_slice(aad);
143-
144-
let block_remaining = poly1305::BLOCK_SIZE.checked_sub(aad.len()).ok_or(Error)?;
145-
if buffer.len() > block_remaining {
146-
let (head, tail) = buffer.split_at(block_remaining);
147-
block[aad.len()..].copy_from_slice(head);
148-
mac.update(&[block]);
149-
Ok(mac.compute_unpadded(tail))
150-
} else {
151-
let msg_len = aad.len().checked_add(buffer.len()).ok_or(Error)?;
152-
block[aad.len()..msg_len].copy_from_slice(buffer);
153-
Ok(mac.compute_unpadded(&block[..msg_len]))
154-
}
155-
}
156-
_ => Err(Error),
138+
// We only support up to one block (16-bytes) of AAD.
139+
// In practice the sizes that matter are `0` and `4` (i.e. length prefix size).
140+
if aad.len() > poly1305::BLOCK_SIZE {
141+
return Err(Error);
157142
}
143+
144+
// Compute a first Poly1305 block which incorporates any AAD.
145+
let mut block = poly1305::Block::default();
146+
block[..aad.len()].copy_from_slice(aad);
147+
148+
let block_remaining = poly1305::BLOCK_SIZE.checked_sub(aad.len()).ok_or(Error)?;
149+
let remaining = if buffer.len() <= block_remaining {
150+
// If total AAD + buffer length is less than or equal to a block, compute a partial block
151+
let msg_len = aad.len().checked_add(buffer.len()).ok_or(Error)?;
152+
block[aad.len()..msg_len].copy_from_slice(buffer);
153+
&block[..msg_len]
154+
} else {
155+
// Compute the first block and return any remaining data
156+
let (head, tail) = buffer.split_at(block_remaining);
157+
block[aad.len()..].copy_from_slice(head);
158+
mac.update(&[block]);
159+
tail
160+
};
161+
162+
// Compute Poly1305 over the remaining message data.
163+
Ok(mac.compute_unpadded(remaining))
158164
}
159165

160166
#[cfg(test)]

0 commit comments

Comments
 (0)