121 lines
3.3 KiB
Rust
121 lines
3.3 KiB
Rust
//! 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<T> = core::result::Result<T, Error>;
|
|
|
|
/// 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;
|