Skip to content

Commit

Permalink
hmac internals: Clarify panic safety of Context::try_sign.
Browse files Browse the repository at this point in the history
Use `Digest::try_finish()` instead of `Digest::finish()`.

Calculate `num_pending` directly from the inner digest, so that the
compiler can use `OutputLen` range analysis to prove that the buffer
is large enough.
  • Loading branch information
briansmith committed Dec 18, 2024
1 parent 08832ab commit 96ca635
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 10 deletions.
9 changes: 5 additions & 4 deletions src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,15 @@ impl Context {
/// `finish` consumes the context so it cannot be (mis-)used after `finish`
/// has been called.
pub fn finish(self) -> Digest {
self.try_finish().unwrap()
let cpu = cpu::features();
self.try_finish(cpu)
.map_err(error::Unspecified::from)
.unwrap()
}

fn try_finish(mut self) -> Result<Digest, error::Unspecified> {
let cpu_features = cpu::features();
pub(crate) fn try_finish(mut self, cpu_features: cpu::Features) -> Result<Digest, FinishError> {
self.block
.try_finish(&mut self.pending, self.num_pending, cpu_features)
.map_err(error::Unspecified::from)
}

/// The algorithm that this context is using.
Expand Down
12 changes: 6 additions & 6 deletions src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,19 +312,19 @@ impl Context {
/// the return value of `sign` to a tag. Use `verify` for verification
/// instead.
pub fn sign(self) -> Tag {
self.try_sign().unwrap()
self.try_sign().map_err(error::Unspecified::from).unwrap()
}

fn try_sign(self) -> Result<Tag, error::Unspecified> {
fn try_sign(self) -> Result<Tag, digest::FinishError> {
let cpu_features = cpu::features();
let algorithm = self.inner.algorithm();
let inner = self.inner.try_finish(cpu_features)?;
let inner = inner.as_ref();
let num_pending = inner.len();
let buffer = &mut [0u8; digest::MAX_BLOCK_LEN];
let num_pending = algorithm.output_len();
buffer[..num_pending].copy_from_slice(self.inner.finish().as_ref());
buffer[..num_pending].copy_from_slice(inner);
self.outer
.try_finish(buffer, num_pending, cpu_features)
.map(Tag)
.map_err(error::Unspecified::from)
}
}

Expand Down

0 comments on commit 96ca635

Please sign in to comment.