//! emsha is the embedded hashing library. It aims to work even in //! `no_std` 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, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.reason { Code::Unknown => write!(f, "unknown error"), Code::OK => write!(f, "OK"), Code::InvalidState => write!(f, "invalid state"), Code::InputTooLong => write!(f, "input is too long"), Code::BufferTooSmall => { write!(f, "output buffer too small") } Code::HashNotFinalized => { write!(f, "hash has not been finalized") } } } } impl Error { /// Construct an error with a `emsha::Code`. pub fn with(reason: Code) -> Self { Self { reason } } } impl error::Error for Error {} #[derive(Clone, Copy, Debug, PartialEq)] /// Common error codes for emsha. pub enum Code { /// This is used internally to denote a Hash is in a good state. OK, /// 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. /// /// That is, the idea is that /// /// `hash.reset();` /// `hash.update(...);` /// `hash.result(...);` /// /// is idempotent, assuming the inputs to update and result are /// constant. The implications of this for a given implementer /// should be described in that type's documentation, but in /// general, it has the effect of preserving any initial state /// while removing any data written to the Hash via the update /// method. fn reset(&mut self) -> Result<()>; /// Write message data into the Hash. fn update(&mut self, msg: &[u8]) -> Result<()>; /// Carry out any final operations on the Hash. /// /// After a call to finalize, no more data can be written. /// Additionally, it transfers out the resulting hash into its /// argument. fn finalize(&mut self, digest: &mut [u8]) -> Result<()>; /// Transfers out the hash to the argument. /// /// The Hash must keep enough state for repeated calls to result /// to work. fn result(&self, digest: &mut [u8]) -> Result<()>; } mod common; pub mod hmac; pub mod sha256;