Minor fixups and doc updates.
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -4,4 +4,4 @@ version = 4
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "emsha"
|
name = "emsha"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ repository = "https://git.wntrmute.dev/wntrmute/emsha-rs"
|
|||||||
categories = ["cryptography", "no-std", "embedded"]
|
categories = ["cryptography", "no-std", "embedded"]
|
||||||
keywords = ["sha256", "hmac", "hash", "embedded", "no_std"]
|
keywords = ["sha256", "hmac", "hash", "embedded", "no_std"]
|
||||||
license-file = "LICENSE"
|
license-file = "LICENSE"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
publish = ["kellnr"]
|
publish = ["kellnr"]
|
||||||
|
|
||||||
|
|||||||
10
src/hmac.rs
10
src/hmac.rs
@@ -1,6 +1,6 @@
|
|||||||
//! HMAC-SHA256 implementation.
|
//! HMAC-SHA256 implementation.
|
||||||
|
|
||||||
use crate::{sha256, Code, Error, Hash, Result};
|
use crate::{Code, Error, Hash, Result, sha256};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::fmt::Formatter;
|
use core::fmt::Formatter;
|
||||||
|
|
||||||
@@ -11,12 +11,13 @@ enum State {
|
|||||||
Finished,
|
Finished,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const KEY_LENGTH: usize = 64;
|
const KEY_LENGTH: usize = 64;
|
||||||
const IPAD: u8 = 0x36;
|
const IPAD: u8 = 0x36;
|
||||||
const OPAD: u8 = 0x5c;
|
const OPAD: u8 = 0x5c;
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
/// HMAC_SHA256 is a keyed message authentication function.
|
||||||
pub struct HMAC_SHA256 {
|
pub struct HMAC_SHA256 {
|
||||||
state: State,
|
state: State,
|
||||||
ctx: sha256::SHA256,
|
ctx: sha256::SHA256,
|
||||||
@@ -36,6 +37,7 @@ impl fmt::Display for HMAC_SHA256 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HMAC_SHA256 {
|
impl HMAC_SHA256 {
|
||||||
|
/// Construct a new HMAC-SHA256 instance with the provided key.
|
||||||
pub fn new(k: &[u8]) -> Result<Self> {
|
pub fn new(k: &[u8]) -> Result<Self> {
|
||||||
let mut ik: [u8; KEY_LENGTH] = [0; KEY_LENGTH];
|
let mut ik: [u8; KEY_LENGTH] = [0; KEY_LENGTH];
|
||||||
let mut ctx = sha256::SHA256::default();
|
let mut ctx = sha256::SHA256::default();
|
||||||
@@ -157,8 +159,4 @@ impl Hash for HMAC_SHA256 {
|
|||||||
|
|
||||||
self.copy_digest(digest)
|
self.copy_digest(digest)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size() -> usize {
|
|
||||||
sha256::SIZE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
43
src/lib.rs
43
src/lib.rs
@@ -1,12 +1,28 @@
|
|||||||
//! emsha is the embedded hashing library. It aims to work even in
|
//! emsha is the embedded hashing library. It aims to work even in
|
||||||
//! nostdenv environments.
|
//! 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]
|
#![no_std]
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
use core::error;
|
use core::error;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
/// Error is a standardized error type for the emsha package.
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
reason: Code,
|
reason: Code,
|
||||||
}
|
}
|
||||||
@@ -16,7 +32,6 @@ impl fmt::Display for Error {
|
|||||||
match self.reason {
|
match self.reason {
|
||||||
Code::Unknown => write!(f, "unknown error"),
|
Code::Unknown => write!(f, "unknown error"),
|
||||||
Code::OK => write!(f, "OK"),
|
Code::OK => write!(f, "OK"),
|
||||||
Code::TestFailure => write!(f, "test failure"),
|
|
||||||
Code::InvalidState => write!(f, "invalid state"),
|
Code::InvalidState => write!(f, "invalid state"),
|
||||||
Code::InputTooLong => write!(f, "input is too long"),
|
Code::InputTooLong => write!(f, "input is too long"),
|
||||||
Code::BufferTooSmall => {
|
Code::BufferTooSmall => {
|
||||||
@@ -30,6 +45,7 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
/// Construct an error with a `emsha::Code`.
|
||||||
pub fn with(reason: Code) -> Self {
|
pub fn with(reason: Code) -> Self {
|
||||||
Self { reason }
|
Self { reason }
|
||||||
}
|
}
|
||||||
@@ -38,18 +54,33 @@ impl Error {
|
|||||||
impl error::Error for Error {}
|
impl error::Error for Error {}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
/// Common error codes for emsha.
|
||||||
pub enum Code {
|
pub enum Code {
|
||||||
Unknown,
|
/// This is used internally to denote a Hash is in a good state.
|
||||||
OK,
|
OK,
|
||||||
TestFailure,
|
|
||||||
|
/// The Hash is in an invalid state and cannot be used except
|
||||||
|
/// maybe via a reset. This is a serious issue.
|
||||||
InvalidState,
|
InvalidState,
|
||||||
|
|
||||||
|
/// The input passed to the hash is too long.
|
||||||
InputTooLong,
|
InputTooLong,
|
||||||
|
|
||||||
|
/// A buffer passed to a hash function was not large enough.
|
||||||
BufferTooSmall,
|
BufferTooSmall,
|
||||||
|
|
||||||
|
/// An attempt was made to get the result of a hash before it was
|
||||||
|
/// finalized.
|
||||||
HashNotFinalized,
|
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>;
|
pub type Result<T> = core::result::Result<T, Error>;
|
||||||
|
|
||||||
|
/// Hash implements a secure hashing algorithm.
|
||||||
pub trait Hash {
|
pub trait Hash {
|
||||||
/// Bring the Hash back to its initial state.
|
/// 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
|
/// The Hash must keep enough state for repeated calls to result
|
||||||
/// to work.
|
/// to work.
|
||||||
fn result(&self, digest: &mut [u8]) -> Result<()>;
|
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;
|
mod common;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//! SHA-256 implementation of the `Hash` type.
|
||||||
|
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::{Code, Error, Hash, Result};
|
use crate::{Code, Error, Hash, Result};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
@@ -26,6 +28,7 @@ const H0: [u32; 8] = [
|
|||||||
|
|
||||||
const MB_SIZE: usize = 64;
|
const MB_SIZE: usize = 64;
|
||||||
|
|
||||||
|
/// SIZE is the output size for a SHA-256 digest.
|
||||||
pub const SIZE: usize = 32;
|
pub const SIZE: usize = 32;
|
||||||
|
|
||||||
fn u32_to_chunk_in_place(x: u32, chunk: &mut [u8]) {
|
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)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
/// SHA-256 is described in RFC 6234.
|
||||||
pub struct SHA256 {
|
pub struct SHA256 {
|
||||||
mlen: u64,
|
mlen: u64,
|
||||||
i_hash: [u32; 8],
|
i_hash: [u32; 8],
|
||||||
@@ -66,6 +70,7 @@ impl Default for SHA256 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SHA256 {
|
impl SHA256 {
|
||||||
|
/// Construct a new SHA256 context.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
mlen: 0,
|
mlen: 0,
|
||||||
@@ -329,10 +334,6 @@ impl Hash for SHA256 {
|
|||||||
self.copy_out_digest(digest);
|
self.copy_out_digest(digest);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size() -> usize {
|
|
||||||
SIZE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_test(input: &[u8], expected: &[u8]) -> Result<()> {
|
fn run_test(input: &[u8], expected: &[u8]) -> Result<()> {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
mod common;
|
mod common;
|
||||||
use common::hexstr;
|
use common::hexstr;
|
||||||
use emsha::{hmac, sha256, Hash, Result};
|
use emsha::{Hash, Result, hmac, sha256};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hmac_00() -> Result<()> {
|
fn test_hmac_00() -> Result<()> {
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ fn test_golden_tests() -> Result<()> {
|
|||||||
let mut s: [u8; 64] = [0; 64];
|
let mut s: [u8; 64] = [0; 64];
|
||||||
|
|
||||||
while i < golden_tests.len() {
|
while i < golden_tests.len() {
|
||||||
eprintln!("golden test: {:}", i);
|
|
||||||
h.update(golden_tests[i].input)?;
|
h.update(golden_tests[i].input)?;
|
||||||
h.finalize(&mut d)?;
|
h.finalize(&mut d)?;
|
||||||
hexstr(&d, &mut s);
|
hexstr(&d, &mut s);
|
||||||
|
|||||||
Reference in New Issue
Block a user