From f80204acedcc51dfce13f7a3ba62cb48a2a565ea Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Mon, 29 Dec 2025 02:03:32 -0700 Subject: [PATCH] Minor fixups and doc updates. --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/hmac.rs | 10 ++++------ src/lib.rs | 43 ++++++++++++++++++++++++++++++++++--------- src/sha256.rs | 9 +++++---- tests/hmac.rs | 2 +- tests/sha256.rs | 1 - 7 files changed, 46 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f0d65b..b97e50a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,4 +4,4 @@ version = 4 [[package]] name = "emsha" -version = "1.0.0" +version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 1179f2e..60c6594 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ repository = "https://git.wntrmute.dev/wntrmute/emsha-rs" categories = ["cryptography", "no-std", "embedded"] keywords = ["sha256", "hmac", "hash", "embedded", "no_std"] license-file = "LICENSE" -version = "1.0.0" +version = "1.0.1" edition = "2024" publish = ["kellnr"] diff --git a/src/hmac.rs b/src/hmac.rs index 069b609..0eceda4 100644 --- a/src/hmac.rs +++ b/src/hmac.rs @@ -1,6 +1,6 @@ //! HMAC-SHA256 implementation. -use crate::{sha256, Code, Error, Hash, Result}; +use crate::{Code, Error, Hash, Result, sha256}; use core::fmt; use core::fmt::Formatter; @@ -11,12 +11,13 @@ enum State { Finished, } -pub const KEY_LENGTH: usize = 64; +const KEY_LENGTH: usize = 64; const IPAD: u8 = 0x36; const OPAD: u8 = 0x5c; #[allow(non_camel_case_types)] #[derive(Debug, Clone, Copy)] +/// HMAC_SHA256 is a keyed message authentication function. pub struct HMAC_SHA256 { state: State, ctx: sha256::SHA256, @@ -36,6 +37,7 @@ impl fmt::Display for HMAC_SHA256 { } impl HMAC_SHA256 { + /// Construct a new HMAC-SHA256 instance with the provided key. pub fn new(k: &[u8]) -> Result { let mut ik: [u8; KEY_LENGTH] = [0; KEY_LENGTH]; let mut ctx = sha256::SHA256::default(); @@ -157,8 +159,4 @@ impl Hash for HMAC_SHA256 { self.copy_digest(digest) } - - fn size() -> usize { - sha256::SIZE - } } diff --git a/src/lib.rs b/src/lib.rs index 7aa2559..f7e195a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,28 @@ //! emsha is the embedded hashing library. It aims to work even in //! nostdenv environments. +//! +//! ## Example SHA256 hashing +//! ``` +//! use emsha::{Hash, sha256}; +//! # use emsha::Result; +//! # fn main() -> Result<()> { +//! let mut h = sha256::SHA256::new(); +//! let mut d: [u8; sha256::SIZE] = [0; sha256::SIZE]; +//! h.update(b"hello, world!")?; +//! h.finalize(&mut d)?; +//! println!("{:?}", d); +//! # Ok(()) +//! # } +//! ``` #![no_std] +#![warn(missing_docs)] use core::error; use core::fmt; #[derive(Clone, Debug)] +/// Error is a standardized error type for the emsha package. pub struct Error { reason: Code, } @@ -16,7 +32,6 @@ impl fmt::Display for Error { match self.reason { Code::Unknown => write!(f, "unknown error"), Code::OK => write!(f, "OK"), - Code::TestFailure => write!(f, "test failure"), Code::InvalidState => write!(f, "invalid state"), Code::InputTooLong => write!(f, "input is too long"), Code::BufferTooSmall => { @@ -30,6 +45,7 @@ impl fmt::Display for Error { } impl Error { + /// Construct an error with a `emsha::Code`. pub fn with(reason: Code) -> Self { Self { reason } } @@ -38,18 +54,33 @@ impl Error { impl error::Error for Error {} #[derive(Clone, Copy, Debug, PartialEq)] +/// Common error codes for emsha. pub enum Code { - Unknown, + /// This is used internally to denote a Hash is in a good state. OK, - TestFailure, + + /// The Hash is in an invalid state and cannot be used except + /// maybe via a reset. This is a serious issue. InvalidState, + + /// The input passed to the hash is too long. InputTooLong, + + /// A buffer passed to a hash function was not large enough. BufferTooSmall, + + /// An attempt was made to get the result of a hash before it was + /// finalized. HashNotFinalized, + + /// An unknown error has occurred. + Unknown, } +/// Result is a convenience type for results returned from this package. pub type Result = core::result::Result; +/// Hash implements a secure hashing algorithm. pub trait Hash { /// Bring the Hash back to its initial state. /// @@ -82,12 +113,6 @@ pub trait Hash { /// The Hash must keep enough state for repeated calls to result /// to work. fn result(&self, digest: &mut [u8]) -> Result<()>; - - /// Return the output size of the Hash. - /// - /// This is how large the buffers written to by result should - /// be. - fn size() -> usize; } mod common; diff --git a/src/sha256.rs b/src/sha256.rs index e2a9f22..17f080a 100644 --- a/src/sha256.rs +++ b/src/sha256.rs @@ -1,3 +1,5 @@ +//! SHA-256 implementation of the `Hash` type. + use crate::common::*; use crate::{Code, Error, Hash, Result}; use core::fmt; @@ -26,6 +28,7 @@ const H0: [u32; 8] = [ const MB_SIZE: usize = 64; +/// SIZE is the output size for a SHA-256 digest. pub const SIZE: usize = 32; fn u32_to_chunk_in_place(x: u32, chunk: &mut [u8]) { @@ -37,6 +40,7 @@ fn u32_to_chunk_in_place(x: u32, chunk: &mut [u8]) { } #[derive(Debug, Clone, Copy)] +/// SHA-256 is described in RFC 6234. pub struct SHA256 { mlen: u64, i_hash: [u32; 8], @@ -66,6 +70,7 @@ impl Default for SHA256 { } impl SHA256 { + /// Construct a new SHA256 context. pub fn new() -> Self { Self { mlen: 0, @@ -329,10 +334,6 @@ impl Hash for SHA256 { self.copy_out_digest(digest); Ok(()) } - - fn size() -> usize { - SIZE - } } fn run_test(input: &[u8], expected: &[u8]) -> Result<()> { diff --git a/tests/hmac.rs b/tests/hmac.rs index 9d3f496..a05e7b6 100644 --- a/tests/hmac.rs +++ b/tests/hmac.rs @@ -1,6 +1,6 @@ mod common; use common::hexstr; -use emsha::{hmac, sha256, Hash, Result}; +use emsha::{Hash, Result, hmac, sha256}; #[test] fn test_hmac_00() -> Result<()> { diff --git a/tests/sha256.rs b/tests/sha256.rs index 32f4644..0b021db 100644 --- a/tests/sha256.rs +++ b/tests/sha256.rs @@ -63,7 +63,6 @@ fn test_golden_tests() -> Result<()> { let mut s: [u8; 64] = [0; 64]; while i < golden_tests.len() { - eprintln!("golden test: {:}", i); h.update(golden_tests[i].input)?; h.finalize(&mut d)?; hexstr(&d, &mut s);