mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-06 16:20:53 +02:00
3da3e12edc
Generate bindgen API with core instead of std Replace C types using std:: with core:: Replace std::mem usage with core::mem
2395 lines
73 KiB
Rust
2395 lines
73 KiB
Rust
/*
|
|
* Copyright (C) 2006-2026 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL.
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
/*!
|
|
This module provides a Rust wrapper for the wolfCrypt library's Secure Hash
|
|
Algorithm (SHA) functionality.
|
|
*/
|
|
|
|
use crate::sys;
|
|
use core::mem::MaybeUninit;
|
|
|
|
/// Context for SHA-1 computation.
|
|
#[cfg(sha)]
|
|
pub struct SHA {
|
|
wc_sha: sys::wc_Sha,
|
|
}
|
|
|
|
#[cfg(sha)]
|
|
impl SHA {
|
|
/// SHA-1 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA;
|
|
/// let sha = SHA::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA;
|
|
/// let sha = SHA::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha: MaybeUninit<sys::wc_Sha> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha_ex(wc_sha.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha = unsafe { wc_sha.assume_init() };
|
|
let sha = SHA { wc_sha };
|
|
Ok(sha)
|
|
}
|
|
|
|
/// Reinitialize a SHA instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA;
|
|
/// let mut sha = SHA::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA instance for a new hash calculation with optional
|
|
/// heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA;
|
|
/// let mut sha = SHA::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha_ex(&mut self.wc_sha, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA;
|
|
/// let mut sha = SHA::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_ShaUpdate(&mut self.wc_sha, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA;
|
|
/// let mut sha = SHA::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_ShaFinal(&mut self.wc_sha, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha)]
|
|
impl Drop for SHA {
|
|
/// Safely free the underlying wolfSSL SHA context.
|
|
///
|
|
/// This calls the `wc_ShaFree` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the SHA
|
|
/// struct goes out of scope, automatically cleaning up resources and
|
|
/// preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_ShaFree(&mut self.wc_sha); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHA-224 (SHA-2) computation.
|
|
#[cfg(sha224)]
|
|
pub struct SHA224 {
|
|
wc_sha224: sys::wc_Sha224,
|
|
}
|
|
|
|
#[cfg(sha224)]
|
|
impl SHA224 {
|
|
/// SHA-224 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA224_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA224 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA224 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA224;
|
|
/// let sha = SHA224::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA224 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA224 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA224;
|
|
/// let sha = SHA224::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha224: MaybeUninit<sys::wc_Sha224> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha224_ex(wc_sha224.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha224 = unsafe { wc_sha224.assume_init() };
|
|
let sha224 = SHA224 { wc_sha224 };
|
|
Ok(sha224)
|
|
}
|
|
|
|
/// Reinitialize a SHA224 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA224;
|
|
/// let mut sha = SHA224::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA224 instance for a new hash calculation with optional
|
|
/// heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA224;
|
|
/// let mut sha = SHA224::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha224_ex(&mut self.wc_sha224, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA-224 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA224;
|
|
/// let mut sha = SHA224::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Sha224Update(&mut self.wc_sha224, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA-224 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA224::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA224;
|
|
/// let mut sha = SHA224::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA224::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_Sha224Final(&mut self.wc_sha224, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha224)]
|
|
impl Drop for SHA224 {
|
|
/// Safely free the underlying wolfSSL SHA224 context.
|
|
///
|
|
/// This calls the `wc_Sha224Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHA224 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Sha224Free(&mut self.wc_sha224); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHA-256 (SHA-2) computation.
|
|
#[cfg(sha256)]
|
|
pub struct SHA256 {
|
|
wc_sha256: sys::wc_Sha256,
|
|
}
|
|
|
|
#[cfg(sha256)]
|
|
impl SHA256 {
|
|
/// SHA-256 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA256_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA256 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA256 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA256;
|
|
/// let sha = SHA256::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA256 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA256 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA256;
|
|
/// let sha = SHA256::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha256: MaybeUninit<sys::wc_Sha256> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha256_ex(wc_sha256.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha256 = unsafe { wc_sha256.assume_init() };
|
|
let sha256 = SHA256 { wc_sha256 };
|
|
Ok(sha256)
|
|
}
|
|
|
|
/// Reinitialize a SHA256 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA256;
|
|
/// let mut sha = SHA256::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA256 instance for a new hash calculation with optional
|
|
/// heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA256;
|
|
/// let mut sha = SHA256::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha256_ex(&mut self.wc_sha256, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA-256 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA256;
|
|
/// let mut sha = SHA256::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Sha256Update(&mut self.wc_sha256, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA-256 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA256::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA256;
|
|
/// let mut sha = SHA256::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA256::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_Sha256Final(&mut self.wc_sha256, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha256)]
|
|
impl Drop for SHA256 {
|
|
/// Safely free the underlying wolfSSL SHA256 context.
|
|
///
|
|
/// This calls the `wc_Sha256Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHA256 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Sha256Free(&mut self.wc_sha256); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHA-384 (SHA-2) computation.
|
|
#[cfg(sha384)]
|
|
pub struct SHA384 {
|
|
wc_sha384: sys::wc_Sha384,
|
|
}
|
|
|
|
#[cfg(sha384)]
|
|
impl SHA384 {
|
|
/// SHA-384 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA384_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA384 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA384 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA384;
|
|
/// let sha = SHA384::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA384 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA384 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA384;
|
|
/// let sha = SHA384::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha384: MaybeUninit<sys::wc_Sha384> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha384_ex(wc_sha384.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha384 = unsafe { wc_sha384.assume_init() };
|
|
let sha384 = SHA384 { wc_sha384 };
|
|
Ok(sha384)
|
|
}
|
|
|
|
/// Reinitialize a SHA384 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA384;
|
|
/// let mut sha = SHA384::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA384 instance for a new hash calculation with optional
|
|
/// heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA384;
|
|
/// let mut sha = SHA384::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha384_ex(&mut self.wc_sha384, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA-384 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA384;
|
|
/// let mut sha = SHA384::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Sha384Update(&mut self.wc_sha384, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA-384 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA384::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA384;
|
|
/// let mut sha = SHA384::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA384::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_Sha384Final(&mut self.wc_sha384, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha384)]
|
|
impl Drop for SHA384 {
|
|
/// Safely free the underlying wolfSSL SHA384 context.
|
|
///
|
|
/// This calls the `wc_Sha384Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHA384 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Sha384Free(&mut self.wc_sha384); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHA-512 (SHA-2) computation.
|
|
#[cfg(sha512)]
|
|
pub struct SHA512 {
|
|
wc_sha512: sys::wc_Sha512,
|
|
}
|
|
|
|
#[cfg(sha512)]
|
|
impl SHA512 {
|
|
/// SHA-512 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA512_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA512 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA512 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA512;
|
|
/// let sha = SHA512::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA512 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA512 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA512;
|
|
/// let sha = SHA512::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha512: MaybeUninit<sys::wc_Sha512> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha512_ex(wc_sha512.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha512 = unsafe { wc_sha512.assume_init() };
|
|
let sha512 = SHA512 { wc_sha512 };
|
|
Ok(sha512)
|
|
}
|
|
|
|
/// Reinitialize a SHA512 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA512;
|
|
/// let mut sha = SHA512::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA512 instance for a new hash calculation with optional
|
|
/// heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA512;
|
|
/// let mut sha = SHA512::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha512_ex(&mut self.wc_sha512, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA-512 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA512;
|
|
/// let mut sha = SHA512::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Sha512Update(&mut self.wc_sha512, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA-512 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA512::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA512;
|
|
/// let mut sha = SHA512::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA512::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_Sha512Final(&mut self.wc_sha512, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha512)]
|
|
impl Drop for SHA512 {
|
|
/// Safely free the underlying wolfSSL SHA512 context.
|
|
///
|
|
/// This calls the `wc_Sha512Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHA512 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Sha512Free(&mut self.wc_sha512); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHA3-224 computation.
|
|
#[cfg(sha3)]
|
|
pub struct SHA3_224 {
|
|
wc_sha3: sys::wc_Sha3,
|
|
}
|
|
|
|
#[cfg(sha3)]
|
|
impl SHA3_224 {
|
|
/// SHA3-224 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA3_224_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA3_224 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA3_224 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_224;
|
|
/// let sha = SHA3_224::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA3_224 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA3_224 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_224;
|
|
/// let sha = SHA3_224::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha3: MaybeUninit<sys::wc_Sha3> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha3_224(wc_sha3.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha3 = unsafe { wc_sha3.assume_init() };
|
|
let sha3_224 = SHA3_224 { wc_sha3 };
|
|
Ok(sha3_224)
|
|
}
|
|
|
|
/// Reinitialize a SHA3_224 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_224;
|
|
/// let mut sha = SHA3_224::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA3_224 instance for a new hash calculation with
|
|
/// optional heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_224;
|
|
/// let mut sha = SHA3_224::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha3_224(&mut self.wc_sha3, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA3-224 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_224;
|
|
/// let mut sha = SHA3_224::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Sha3_224_Update(&mut self.wc_sha3, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA3-224 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA3_224::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_224;
|
|
/// let mut sha = SHA3_224::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA3_224::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_Sha3_224_Final(&mut self.wc_sha3, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha3)]
|
|
impl Drop for SHA3_224 {
|
|
/// Safely free the underlying wolfSSL SHA3_224 context.
|
|
///
|
|
/// This calls the `wc_Sha3_224_Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHA3_224 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Sha3_224_Free(&mut self.wc_sha3); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHA3-256 computation.
|
|
#[cfg(sha3)]
|
|
pub struct SHA3_256 {
|
|
wc_sha3: sys::wc_Sha3,
|
|
}
|
|
|
|
#[cfg(sha3)]
|
|
impl SHA3_256 {
|
|
/// SHA3-256 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA3_256_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA3_256 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA3_256 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_256;
|
|
/// let sha = SHA3_256::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA3_256 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA3_256 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_256;
|
|
/// let sha = SHA3_256::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha3: MaybeUninit<sys::wc_Sha3> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha3_256(wc_sha3.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha3 = unsafe { wc_sha3.assume_init() };
|
|
let sha3_256 = SHA3_256 { wc_sha3 };
|
|
Ok(sha3_256)
|
|
}
|
|
|
|
/// Reinitialize a SHA3_256 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_256;
|
|
/// let mut sha = SHA3_256::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA3_256 instance for a new hash calculation with
|
|
/// optional heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_256;
|
|
/// let mut sha = SHA3_256::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha3_256(&mut self.wc_sha3, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA3-256 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_256;
|
|
/// let mut sha = SHA3_256::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Sha3_256_Update(&mut self.wc_sha3, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA3-256 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA3_256::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_256;
|
|
/// let mut sha = SHA3_256::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA3_256::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_Sha3_256_Final(&mut self.wc_sha3, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha3)]
|
|
impl Drop for SHA3_256 {
|
|
/// Safely free the underlying wolfSSL SHA3_256 context.
|
|
///
|
|
/// This calls the `wc_Sha3_256_Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHA3_256 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Sha3_256_Free(&mut self.wc_sha3); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHA3-384 computation.
|
|
#[cfg(sha3)]
|
|
pub struct SHA3_384 {
|
|
wc_sha3: sys::wc_Sha3,
|
|
}
|
|
|
|
#[cfg(sha3)]
|
|
impl SHA3_384 {
|
|
/// SHA3-384 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA3_384_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA3_384 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA3_384 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_384;
|
|
/// let sha = SHA3_384::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA3_384 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA3_384 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_384;
|
|
/// let sha = SHA3_384::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha3: MaybeUninit<sys::wc_Sha3> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha3_384(wc_sha3.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha3 = unsafe { wc_sha3.assume_init() };
|
|
let sha3_384 = SHA3_384 { wc_sha3 };
|
|
Ok(sha3_384)
|
|
}
|
|
|
|
/// Reinitialize a SHA3_384 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_384;
|
|
/// let mut sha = SHA3_384::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA3_384 instance for a new hash calculation with
|
|
/// optional heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_384;
|
|
/// let mut sha = SHA3_384::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha3_384(&mut self.wc_sha3, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA3-384 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_384;
|
|
/// let mut sha = SHA3_384::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Sha3_384_Update(&mut self.wc_sha3, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA3-384 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA3_384::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_384;
|
|
/// let mut sha = SHA3_384::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA3_384::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_Sha3_384_Final(&mut self.wc_sha3, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha3)]
|
|
impl Drop for SHA3_384 {
|
|
/// Safely free the underlying wolfSSL SHA3_384 context.
|
|
///
|
|
/// This calls the `wc_Sha3_384_Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHA3_384 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Sha3_384_Free(&mut self.wc_sha3); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHA3-512 computation.
|
|
#[cfg(sha3)]
|
|
pub struct SHA3_512 {
|
|
wc_sha3: sys::wc_Sha3,
|
|
}
|
|
|
|
#[cfg(sha3)]
|
|
impl SHA3_512 {
|
|
/// SHA3-512 digest size in bytes.
|
|
pub const DIGEST_SIZE: usize = sys::WC_SHA3_512_DIGEST_SIZE as usize;
|
|
|
|
/// Build a new SHA3_512 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA3_512 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_512;
|
|
/// let sha = SHA3_512::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHA3_512 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHA3_512 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_512;
|
|
/// let sha = SHA3_512::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_sha3: MaybeUninit<sys::wc_Sha3> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha3_512(wc_sha3.as_mut_ptr(), heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_sha3 = unsafe { wc_sha3.assume_init() };
|
|
let sha3_512 = SHA3_512 { wc_sha3 };
|
|
Ok(sha3_512)
|
|
}
|
|
|
|
/// Reinitialize a SHA3_512 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_512;
|
|
/// let mut sha = SHA3_512::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHA3_512 instance for a new hash calculation with
|
|
/// optional heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_512;
|
|
/// let mut sha = SHA3_512::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe { sys::wc_InitSha3_512(&mut self.wc_sha3, heap, dev_id) };
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHA3-512 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_512;
|
|
/// let mut sha = SHA3_512::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Sha3_512_Update(&mut self.wc_sha3, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHA3-512 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash. The length
|
|
/// should be SHA3_512::DIGEST_SIZE.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHA3_512;
|
|
/// let mut sha = SHA3_512::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; SHA3_512::DIGEST_SIZE];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
if hash.len() != Self::DIGEST_SIZE {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let rc = unsafe {
|
|
sys::wc_Sha3_512_Final(&mut self.wc_sha3, hash.as_mut_ptr())
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(sha3)]
|
|
impl Drop for SHA3_512 {
|
|
/// Safely free the underlying wolfSSL SHA3_512 context.
|
|
///
|
|
/// This calls the `wc_Sha3_512_Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHA3_512 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Sha3_512_Free(&mut self.wc_sha3); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHAKE128 (SHA-3) computation.
|
|
#[cfg(shake128)]
|
|
pub struct SHAKE128 {
|
|
wc_shake: sys::wc_Shake,
|
|
}
|
|
|
|
#[cfg(shake128)]
|
|
impl SHAKE128 {
|
|
/// Squeeze block size.
|
|
pub const SQUEEZE_BLOCK_SIZE: usize = sys::WC_SHA3_128_BLOCK_SIZE as usize;
|
|
|
|
/// Build a new SHAKE128 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHAKE128 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE128;
|
|
/// let sha = SHAKE128::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHAKE128 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHAKE128 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE128;
|
|
/// let sha = SHAKE128::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_shake: MaybeUninit<sys::wc_Shake> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe {
|
|
sys::wc_InitShake128(wc_shake.as_mut_ptr(), heap, dev_id)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_shake = unsafe { wc_shake.assume_init() };
|
|
let shake128 = SHAKE128 { wc_shake };
|
|
Ok(shake128)
|
|
}
|
|
|
|
/// Reinitialize a SHAKE128 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE128;
|
|
/// let mut sha = SHAKE128::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHAKE128 instance for a new hash calculation with
|
|
/// optional heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE128;
|
|
/// let mut sha = SHAKE128::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe {
|
|
sys::wc_InitShake128(&mut self.wc_shake, heap, dev_id)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHAKE128 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE128;
|
|
/// let mut sha = SHAKE128::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Shake128_Update(&mut self.wc_shake, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHAKE128 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE128;
|
|
/// let mut sha = SHAKE128::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; 32];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
let hash_size = hash.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Shake128_Final(&mut self.wc_shake, hash.as_mut_ptr(), hash_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Absorb the provided byte array. Cannot be called incrementally.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Data buffer to absorb.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE128;
|
|
/// let mut sha = SHAKE128::new().expect("Error with new()");
|
|
/// sha.absorb(b"input").expect("Error with absorb()");
|
|
/// ```
|
|
pub fn absorb(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Shake128_Absorb(&mut self.wc_shake, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Squeeze out more blocks of data.
|
|
///
|
|
/// This function can be called inrementally.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `dout`: Output buffer.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE128;
|
|
/// let mut sha = SHAKE128::new().expect("Error with new()");
|
|
/// sha.absorb(b"input").expect("Error with absorb()");
|
|
/// let mut buffer = [0u8; 2 * SHAKE128::SQUEEZE_BLOCK_SIZE];
|
|
/// sha.squeeze_blocks(&mut buffer).expect("Error with squeeze_blocks()");
|
|
/// ```
|
|
pub fn squeeze_blocks(&mut self, dout: &mut [u8]) -> Result<(), i32> {
|
|
let dout_size = dout.len() as u32;
|
|
if dout_size % (Self::SQUEEZE_BLOCK_SIZE as u32) != 0 {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let n_blocks = dout_size / (Self::SQUEEZE_BLOCK_SIZE as u32);
|
|
let rc = unsafe {
|
|
sys::wc_Shake128_SqueezeBlocks(&mut self.wc_shake, dout.as_mut_ptr(), n_blocks)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(shake128)]
|
|
impl Drop for SHAKE128 {
|
|
/// Safely free the underlying wolfSSL SHAKE128 context.
|
|
///
|
|
/// This calls the `wc_Shake128_Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHAKE128 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Shake128_Free(&mut self.wc_shake); }
|
|
}
|
|
}
|
|
|
|
/// Context for SHAKE256 (SHA-3) computation.
|
|
#[cfg(shake256)]
|
|
pub struct SHAKE256 {
|
|
wc_shake: sys::wc_Shake,
|
|
}
|
|
|
|
#[cfg(shake256)]
|
|
impl SHAKE256 {
|
|
/// Squeeze block size.
|
|
pub const SQUEEZE_BLOCK_SIZE: usize = sys::WC_SHA3_256_BLOCK_SIZE as usize;
|
|
|
|
/// Build a new SHAKE256 instance.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHAKE256 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE256;
|
|
/// let sha = SHAKE256::new().expect("Error with new()");
|
|
/// ```
|
|
pub fn new() -> Result<Self, i32> {
|
|
Self::new_ex(None, None)
|
|
}
|
|
|
|
/// Build a new SHAKE256 instance with optional heap and device ID.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(sha) containing the SHAKE256 struct instance or Err(e)
|
|
/// containing the wolfSSL library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE256;
|
|
/// let sha = SHAKE256::new_ex(None, None).expect("Error with new_ex()");
|
|
/// ```
|
|
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
|
let mut wc_shake: MaybeUninit<sys::wc_Shake> = MaybeUninit::uninit();
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe {
|
|
sys::wc_InitShake256(wc_shake.as_mut_ptr(), heap, dev_id)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
let wc_shake = unsafe { wc_shake.assume_init() };
|
|
let shake256 = SHAKE256 { wc_shake };
|
|
Ok(shake256)
|
|
}
|
|
|
|
/// Reinitialize a SHAKE256 instance for a new hash calculation.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE256;
|
|
/// let mut sha = SHAKE256::new().expect("Error with new()");
|
|
/// sha.init().expect("Error with init()");
|
|
/// ```
|
|
pub fn init(&mut self) -> Result<(), i32> {
|
|
self.init_ex(None, None)
|
|
}
|
|
|
|
/// Reinitialize a SHAKE256 instance for a new hash calculation with
|
|
/// optional heap and device ID.
|
|
///
|
|
/// This does not need to be called after `new()`, but should be called
|
|
/// after a hash calculation to prepare for a new calculation.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `heap`: Optional heap hint.
|
|
/// * `dev_id` Optional device ID to use with crypto callbacks or async hardware.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE256;
|
|
/// let mut sha = SHAKE256::new().expect("Error with new()");
|
|
/// sha.init_ex(None, None).expect("Error with init_ex()");
|
|
/// ```
|
|
pub fn init_ex(&mut self, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<(), i32> {
|
|
let heap = match heap {
|
|
Some(heap) => heap,
|
|
None => core::ptr::null_mut(),
|
|
};
|
|
let dev_id = match dev_id {
|
|
Some(dev_id) => dev_id,
|
|
None => sys::INVALID_DEVID,
|
|
};
|
|
let rc = unsafe {
|
|
sys::wc_InitShake256(&mut self.wc_shake, heap, dev_id)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the SHAKE256 calculation by feeding in more input data.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Input data.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE256;
|
|
/// let mut sha = SHAKE256::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// ```
|
|
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Shake256_Update(&mut self.wc_shake, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Finalize the SHAKE256 calculation and retrieve the calculated hash.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `hash`: Buffer in which to store the calculated hash.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE256;
|
|
/// let mut sha = SHAKE256::new().expect("Error with new()");
|
|
/// sha.update(b"input").expect("Error with update()");
|
|
/// let mut hash = [0u8; 32];
|
|
/// sha.finalize(&mut hash).expect("Error with finalize()");
|
|
/// ```
|
|
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
|
|
let hash_size = hash.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Shake256_Final(&mut self.wc_shake, hash.as_mut_ptr(), hash_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Absorb the provided byte array. Cannot be called incrementally.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `data`: Data buffer to absorb.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE256;
|
|
/// let mut sha = SHAKE256::new().expect("Error with new()");
|
|
/// sha.absorb(b"input").expect("Error with absorb()");
|
|
/// ```
|
|
pub fn absorb(&mut self, data: &[u8]) -> Result<(), i32> {
|
|
let data_size = data.len() as u32;
|
|
let rc = unsafe {
|
|
sys::wc_Shake256_Absorb(&mut self.wc_shake, data.as_ptr(), data_size)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Squeeze out more blocks of data.
|
|
///
|
|
/// This function can be called inrementally.
|
|
///
|
|
/// # Parameters
|
|
///
|
|
/// * `dout`: Output buffer.
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
|
/// library error code value.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use wolfssl_wolfcrypt::sha::SHAKE256;
|
|
/// let mut sha = SHAKE256::new().expect("Error with new()");
|
|
/// sha.absorb(b"input").expect("Error with absorb()");
|
|
/// let mut buffer = [0u8; 2 * SHAKE256::SQUEEZE_BLOCK_SIZE];
|
|
/// sha.squeeze_blocks(&mut buffer).expect("Error with squeeze_blocks()");
|
|
/// ```
|
|
pub fn squeeze_blocks(&mut self, dout: &mut [u8]) -> Result<(), i32> {
|
|
let dout_size = dout.len() as u32;
|
|
if dout_size % (Self::SQUEEZE_BLOCK_SIZE as u32) != 0 {
|
|
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
|
}
|
|
let n_blocks = dout_size / (Self::SQUEEZE_BLOCK_SIZE as u32);
|
|
let rc = unsafe {
|
|
sys::wc_Shake256_SqueezeBlocks(&mut self.wc_shake, dout.as_mut_ptr(), n_blocks)
|
|
};
|
|
if rc != 0 {
|
|
return Err(rc);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(shake256)]
|
|
impl Drop for SHAKE256 {
|
|
/// Safely free the underlying wolfSSL SHAKE256 context.
|
|
///
|
|
/// This calls the `wc_Shake256_Free` wolfssl library function.
|
|
///
|
|
/// The Rust Drop trait guarantees that this method is called when the
|
|
/// SHAKE256 struct goes out of scope, automatically cleaning up resources
|
|
/// and preventing memory leaks.
|
|
fn drop(&mut self) {
|
|
unsafe { sys::wc_Shake256_Free(&mut self.wc_shake); }
|
|
}
|
|
}
|