feat: Block on sha calls, remove Option<> results

This commit is contained in:
Sergio Gasquez 2025-01-07 12:23:49 +01:00
parent c49720f569
commit efcbebdb3d
2 changed files with 40 additions and 58 deletions

View File

@ -40,15 +40,13 @@
//! // desired length
//! let mut output = [0u8; 32];
//!
//! let source_data = loop {
//! if let Some(data) = hasher.finish(&mut output) {
//! break data;
//! }
//! while !source_data.is_empty() {
//! source_data = hasher.update(source_data);
//! };
//!
//! // Finish can be called as many times as desired to get multiple copies of
//! // the output.
//! while hasher.finish(output.as_mut_slice()).is_none() {}
//! hasher.finish(output.as_mut_slice());
//! # }
//! ```
//! ## Implementation State
@ -206,7 +204,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
}
/// Updates the SHA digest with the provided data buffer.
pub fn update<'a>(&mut self, incoming: &'a [u8]) -> Option<&'a [u8]> {
pub fn update<'a>(&mut self, incoming: &'a [u8]) -> &'a [u8] {
self.finished = false;
self.write_data(incoming)
@ -219,11 +217,11 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
/// Typically, output is expected to be the size of
/// [ShaAlgorithm::DIGEST_LENGTH], but smaller inputs can be given to
/// get a "short hash"
pub fn finish(&mut self, output: &mut [u8]) -> Option<()> {
pub fn finish(&mut self, output: &mut [u8]) {
// Store message length for padding
let length = (self.cursor as u64 * 8).to_be_bytes();
// Append "1" bit
self.update(&[0x80])?;
self.update(&[0x80]);
// Flush partial data, ensures aligned cursor
{
@ -306,16 +304,12 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
self.first_run = true;
self.cursor = 0;
self.alignment_helper.reset();
Some(())
}
/// Save the current state of the digest for later continuation.
#[cfg(not(esp32))]
pub fn save(&mut self, context: &mut Context<A>) -> Option<()> {
if self.is_busy() {
return None;
}
pub fn save(&mut self, context: &mut Context<A>) {
while self.is_busy() {}
context.alignment_helper = self.alignment_helper.clone();
context.cursor = self.cursor;
@ -338,8 +332,6 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
32,
);
}
Some(())
}
/// Discard the current digest and return the peripheral.
@ -379,18 +371,18 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
}
}
fn write_data<'a>(&mut self, incoming: &'a [u8]) -> Option<&'a [u8]> {
fn write_data<'a>(&mut self, incoming: &'a [u8]) -> &'a [u8] {
if self.message_buffer_is_full {
if self.is_busy() {
// The message buffer is full and the hardware is still processing the previous
// message. There's nothing to be done besides wait for the hardware.
return None;
} else {
// Submit the full buffer.
self.process_buffer();
// The buffer is now free for filling.
self.message_buffer_is_full = false;
while (&*&*&*self).is_busy() {
// The message buffer is full and the hardware is still
// processing the previous message. There's
// nothing to be done besides wait for the hardware.
}
// Submit the full buffer.
self.process_buffer();
// The buffer is now free for filling.
self.message_buffer_is_full = false;
}
let mod_cursor = self.cursor % A::CHUNK_LENGTH;
@ -418,7 +410,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
}
}
Some(remaining)
remaining
}
}
@ -536,8 +528,8 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::OutputSizeUser for ShaD
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::Update for ShaDigest<'d, A, S> {
fn update(&mut self, data: &[u8]) {
let mut remaining = data.as_ref();
while let Some(rem) = Self::update(self, remaining) {
remaining = rem;
while !remaining.is_empty() {
remaining = self.update(remaining);
}
}
}
@ -545,7 +537,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::Update for ShaDigest<'d
#[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::FixedOutput for ShaDigest<'d, A, S> {
fn finalize_into(mut self, out: &mut digest::Output<Self>) {
while self.finish(out).is_none() {}
self.finish(out);
}
}

View File

@ -33,10 +33,10 @@ fn assert_sw_hash<D: Digest>(input: &[u8], expected_output: &[u8]) {
fn hash_sha<S: ShaAlgorithm>(sha: &mut Sha<'static>, mut input: &[u8], output: &mut [u8]) {
let mut digest = sha.start::<S>();
while let Some(digest) = digest.update(input) {
input = digest;
while !input.is_empty() {
input = digest.update(input);
}
while digest.finish(output).is_none() {}
digest.finish(output);
}
fn hash_digest<'a, S: ShaAlgorithm>(sha: &'a mut Sha<'static>, input: &[u8], output: &mut [u8]) {
@ -268,28 +268,22 @@ mod tests {
let mut all_done = true;
if !sha1_remaining.is_empty() {
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha1);
while let Some(remaining) = digest.update(sha1_remaining) {
sha1_remaining = remaining;
}
while digest.save(&mut sha1).is_none() {}
sha1_remaining = digest.update(sha1_remaining);
digest.save(&mut sha1);
all_done = false;
}
#[cfg(not(feature = "esp32"))]
if !sha224_remaining.is_empty() {
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha224);
while let Some(remaining) = digest.update(sha224_remaining) {
sha224_remaining = remaining;
}
while digest.save(&mut sha224).is_none() {}
sha224_remaining = digest.update(sha224_remaining);
digest.save(&mut sha224);
all_done = false;
}
if !sha256_remaining.is_empty() {
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha256);
while let Some(remaining) = digest.update(sha256_remaining) {
sha256_remaining = remaining;
}
while digest.save(&mut sha256).is_none() {}
sha256_remaining = digest.update(sha256_remaining);
digest.save(&mut sha256);
all_done = false;
}
@ -297,19 +291,15 @@ mod tests {
{
if !sha384_remaining.is_empty() {
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha384);
while let Some(remaining) = digest.update(sha384_remaining) {
sha384_remaining = remaining;
}
while digest.save(&mut sha384).is_none() {}
sha384_remaining = digest.update(sha384_remaining);
digest.save(&mut sha384);
all_done = false;
}
if !sha512_remaining.is_empty() {
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha512);
while let Some(remaining) = digest.update(sha512_remaining) {
sha512_remaining = remaining;
}
while digest.save(&mut sha512).is_none() {}
sha512_remaining = digest.update(sha512_remaining);
digest.save(&mut sha512);
all_done = false;
}
}
@ -320,17 +310,17 @@ mod tests {
}
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha1);
while digest.finish(sha1_p.1).is_none() {}
digest.finish(sha1_p.1);
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha224);
while digest.finish(sha224_p.1).is_none() {}
digest.finish(sha224_p.1);
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha256);
while digest.finish(sha256_p.1).is_none() {}
digest.finish(sha256_p.1);
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
{
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha384);
while digest.finish(sha384_p.1).is_none() {}
digest.finish(sha384_p.1);
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha512);
while digest.finish(sha512_p.1).is_none() {}
digest.finish(sha512_p.1);
}
});
}