Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions wrapper/rust/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

EXTRA_DIST += wrapper/rust/Makefile
EXTRA_DIST += wrapper/rust/README.md
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/Cargo.lock
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/Cargo.toml
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/Makefile
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/README.md
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/build.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/headers.h
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/aes.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/blake2.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/cmac.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/dh.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs
Expand All @@ -26,6 +28,7 @@ EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/rsa.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/sha.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/sys.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_aes.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_cmac.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_dh.rs
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_ecc.rs
Expand Down
4 changes: 4 additions & 0 deletions wrapper/rust/wolfssl-wolfcrypt/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ fn scan_cfg() -> Result<()> {
check_cfg(&binding, "wc_AesXtsInit", "aes_xts");
check_cfg(&binding, "wc_AesXtsEncryptInit", "aes_xts_stream");

/* blake2 */
check_cfg(&binding, "wc_InitBlake2b", "blake2b");
check_cfg(&binding, "wc_InitBlake2s", "blake2s");

/* cmac */
check_cfg(&binding, "wc_InitCmac", "cmac");

Expand Down
305 changes: 305 additions & 0 deletions wrapper/rust/wolfssl-wolfcrypt/src/blake2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
/*
* Copyright (C) 2025 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 BLAKE2
functionality.
*/

use crate::sys;
use std::mem::MaybeUninit;

/// Context for BLAKE2b computation.
#[cfg(blake2b)]
pub struct BLAKE2b {
wc_blake2b: sys::Blake2b,
}

#[cfg(blake2b)]
impl BLAKE2b {
/// Build a new BLAKE2b instance.
///
/// # Parameters
///
/// * `digest_size`: Length of the blake 2 digest to implement.
///
/// # Returns
///
/// Returns either Ok(blake2b) containing the BLAKE2b struct instance or
/// Err(e) containing the wolfSSL library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl_wolfcrypt::blake2::BLAKE2b;
/// let blake2b = BLAKE2b::new(64).expect("Error with new()");
/// ```
pub fn new(digest_size: usize) -> Result<Self, i32> {
let digest_size = digest_size as u32;
let mut wc_blake2b: MaybeUninit<sys::Blake2b> = MaybeUninit::uninit();
let rc = unsafe {
sys::wc_InitBlake2b(wc_blake2b.as_mut_ptr(), digest_size)
};
if rc != 0 {
return Err(rc);
}
let wc_blake2b = unsafe { wc_blake2b.assume_init() };
let blake2b = BLAKE2b { wc_blake2b };
Ok(blake2b)
}

/// Build a new BLAKE2b instance.
///
/// # Parameters
///
/// * `digest_size`: Length of the blake 2 digest to implement.
/// * `key`: Key to use for BLAKE2b operation.
///
/// # Returns
///
/// Returns either Ok(blake2b) containing the BLAKE2b struct instance or
/// Err(e) containing the wolfSSL library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl_wolfcrypt::blake2::BLAKE2b;
/// let key = [42u8; 32];
/// let blake2b = BLAKE2b::new_with_key(64, &key).expect("Error with new()");
/// ```
pub fn new_with_key(digest_size: usize, key: &[u8]) -> Result<Self, i32> {
let digest_size = digest_size as u32;
let mut wc_blake2b: MaybeUninit<sys::Blake2b> = MaybeUninit::uninit();
let key_size = key.len() as u32;
let rc = unsafe {
sys::wc_InitBlake2b_WithKey(wc_blake2b.as_mut_ptr(), digest_size,
key.as_ptr(), key_size)
};
if rc != 0 {
return Err(rc);
}
let wc_blake2b = unsafe { wc_blake2b.assume_init() };
let blake2b = BLAKE2b { wc_blake2b };
Ok(blake2b)
}

/// Update the BLAKE2b hash with the input data.
///
/// This method may be called several times and then the finalize()
/// method should be called to retrieve the final hash.
///
/// # Parameters
///
/// * `data`: Input data to hash.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl_wolfcrypt::blake2::BLAKE2b;
/// let mut blake2b = BLAKE2b::new(64).expect("Error with new()");
/// blake2b.update(&[0u8; 16]).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_Blake2bUpdate(&mut self.wc_blake2b, data.as_ptr(), data_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}

/// Compute and retrieve the final BLAKE2b hash value.
///
/// # Parameters
///
/// * `hash`: Output buffer in which to store the computed BLAKE2b hash
/// value. It can be any length.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl_wolfcrypt::blake2::BLAKE2b;
/// let mut blake2b = BLAKE2b::new(64).expect("Error with new()");
/// blake2b.update(&[0u8; 16]).expect("Error with update()");
/// let mut hash = [0u8; 64];
/// blake2b.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_Blake2bFinal(&mut self.wc_blake2b, hash.as_mut_ptr(), hash_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}

/// Context for BLAKE2s computation.
#[cfg(blake2s)]
pub struct BLAKE2s {
wc_blake2s: sys::Blake2s,
}

#[cfg(blake2s)]
impl BLAKE2s {
/// Build a new BLAKE2s instance.
///
/// # Parameters
///
/// * `digest_size`: Length of the blake 2 digest to implement.
///
/// # Returns
///
/// Returns either Ok(blake2s) containing the BLAKE2s struct instance or
/// Err(e) containing the wolfSSL library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
/// let blake2s = BLAKE2s::new(32).expect("Error with new()");
/// ```
pub fn new(digest_size: usize) -> Result<Self, i32> {
let digest_size = digest_size as u32;
let mut wc_blake2s: MaybeUninit<sys::Blake2s> = MaybeUninit::uninit();
let rc = unsafe {
sys::wc_InitBlake2s(wc_blake2s.as_mut_ptr(), digest_size)
};
if rc != 0 {
return Err(rc);
}
let wc_blake2s = unsafe { wc_blake2s.assume_init() };
let blake2s = BLAKE2s { wc_blake2s };
Ok(blake2s)
}

/// Build a new BLAKE2s instance.
///
/// # Parameters
///
/// * `digest_size`: Length of the blake 2 digest to implement.
/// * `key`: Key to use for BLAKE2s operation.
///
/// # Returns
///
/// Returns either Ok(blake2s) containing the BLAKE2s struct instance or
/// Err(e) containing the wolfSSL library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
/// let key = [42u8; 32];
/// let blake2s = BLAKE2s::new_with_key(32, &key).expect("Error with new()");
/// ```
pub fn new_with_key(digest_size: usize, key: &[u8]) -> Result<Self, i32> {
let digest_size = digest_size as u32;
let mut wc_blake2s: MaybeUninit<sys::Blake2s> = MaybeUninit::uninit();
let key_size = key.len() as u32;
let rc = unsafe {
sys::wc_InitBlake2s_WithKey(wc_blake2s.as_mut_ptr(), digest_size,
key.as_ptr(), key_size)
};
if rc != 0 {
return Err(rc);
}
let wc_blake2s = unsafe { wc_blake2s.assume_init() };
let blake2s = BLAKE2s { wc_blake2s };
Ok(blake2s)
}

/// Update the BLAKE2s hash with the input data.
///
/// This method may be called several times and then the finalize()
/// method should be called to retrieve the final hash.
///
/// # Parameters
///
/// * `data`: Input data to hash.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
/// let mut blake2s = BLAKE2s::new(32).expect("Error with new()");
/// blake2s.update(&[0u8; 16]).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_Blake2sUpdate(&mut self.wc_blake2s, data.as_ptr(), data_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}

/// Compute and retrieve the final BLAKE2s hash value.
///
/// # Parameters
///
/// * `hash`: Output buffer in which to store the computed BLAKE2s hash
/// value. It can be any length.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
/// let mut blake2s = BLAKE2s::new(32).expect("Error with new()");
/// blake2s.update(&[0u8; 16]).expect("Error with update()");
/// let mut hash = [0u8; 64];
/// blake2s.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_Blake2sFinal(&mut self.wc_blake2s, hash.as_mut_ptr(), hash_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
1 change: 1 addition & 0 deletions wrapper/rust/wolfssl-wolfcrypt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
pub mod sys;

pub mod aes;
pub mod blake2;
pub mod cmac;
pub mod dh;
pub mod ecc;
Expand Down
Loading