Skip to content

Commit 5dee8dd

Browse files
authored
Merge pull request #9586 from holtrop-wolfssl/rust-blake2
Rust wrapper: add wolfssl_wolfcrypt::blake2 module
2 parents ea8af7a + bbac280 commit 5dee8dd

File tree

5 files changed

+401
-0
lines changed

5 files changed

+401
-0
lines changed

wrapper/rust/include.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
EXTRA_DIST += wrapper/rust/Makefile
66
EXTRA_DIST += wrapper/rust/README.md
7+
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/CHANGELOG.md
78
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/Cargo.lock
89
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/Cargo.toml
910
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/Makefile
1011
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/README.md
1112
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/build.rs
1213
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/headers.h
1314
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/aes.rs
15+
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/blake2.rs
1416
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/cmac.rs
1517
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/dh.rs
1618
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs
@@ -26,6 +28,7 @@ EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/rsa.rs
2628
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/sha.rs
2729
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/sys.rs
2830
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_aes.rs
31+
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2.rs
2932
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_cmac.rs
3033
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_dh.rs
3134
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_ecc.rs

wrapper/rust/wolfssl-wolfcrypt/build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ fn scan_cfg() -> Result<()> {
126126
check_cfg(&binding, "wc_AesXtsInit", "aes_xts");
127127
check_cfg(&binding, "wc_AesXtsEncryptInit", "aes_xts_stream");
128128

129+
/* blake2 */
130+
check_cfg(&binding, "wc_InitBlake2b", "blake2b");
131+
check_cfg(&binding, "wc_InitBlake2s", "blake2s");
132+
129133
/* cmac */
130134
check_cfg(&binding, "wc_InitCmac", "cmac");
131135

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
/*
2+
* Copyright (C) 2025 wolfSSL Inc.
3+
*
4+
* This file is part of wolfSSL.
5+
*
6+
* wolfSSL is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* wolfSSL is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
19+
*/
20+
21+
/*!
22+
This module provides a Rust wrapper for the wolfCrypt library's BLAKE2
23+
functionality.
24+
*/
25+
26+
use crate::sys;
27+
use std::mem::MaybeUninit;
28+
29+
/// Context for BLAKE2b computation.
30+
#[cfg(blake2b)]
31+
pub struct BLAKE2b {
32+
wc_blake2b: sys::Blake2b,
33+
}
34+
35+
#[cfg(blake2b)]
36+
impl BLAKE2b {
37+
/// Build a new BLAKE2b instance.
38+
///
39+
/// # Parameters
40+
///
41+
/// * `digest_size`: Length of the blake 2 digest to implement.
42+
///
43+
/// # Returns
44+
///
45+
/// Returns either Ok(blake2b) containing the BLAKE2b struct instance or
46+
/// Err(e) containing the wolfSSL library error code value.
47+
///
48+
/// # Example
49+
///
50+
/// ```rust
51+
/// use wolfssl_wolfcrypt::blake2::BLAKE2b;
52+
/// let blake2b = BLAKE2b::new(64).expect("Error with new()");
53+
/// ```
54+
pub fn new(digest_size: usize) -> Result<Self, i32> {
55+
let digest_size = digest_size as u32;
56+
let mut wc_blake2b: MaybeUninit<sys::Blake2b> = MaybeUninit::uninit();
57+
let rc = unsafe {
58+
sys::wc_InitBlake2b(wc_blake2b.as_mut_ptr(), digest_size)
59+
};
60+
if rc != 0 {
61+
return Err(rc);
62+
}
63+
let wc_blake2b = unsafe { wc_blake2b.assume_init() };
64+
let blake2b = BLAKE2b { wc_blake2b };
65+
Ok(blake2b)
66+
}
67+
68+
/// Build a new BLAKE2b instance.
69+
///
70+
/// # Parameters
71+
///
72+
/// * `digest_size`: Length of the blake 2 digest to implement.
73+
/// * `key`: Key to use for BLAKE2b operation.
74+
///
75+
/// # Returns
76+
///
77+
/// Returns either Ok(blake2b) containing the BLAKE2b struct instance or
78+
/// Err(e) containing the wolfSSL library error code value.
79+
///
80+
/// # Example
81+
///
82+
/// ```rust
83+
/// use wolfssl_wolfcrypt::blake2::BLAKE2b;
84+
/// let key = [42u8; 32];
85+
/// let blake2b = BLAKE2b::new_with_key(64, &key).expect("Error with new()");
86+
/// ```
87+
pub fn new_with_key(digest_size: usize, key: &[u8]) -> Result<Self, i32> {
88+
let digest_size = digest_size as u32;
89+
let mut wc_blake2b: MaybeUninit<sys::Blake2b> = MaybeUninit::uninit();
90+
let key_size = key.len() as u32;
91+
let rc = unsafe {
92+
sys::wc_InitBlake2b_WithKey(wc_blake2b.as_mut_ptr(), digest_size,
93+
key.as_ptr(), key_size)
94+
};
95+
if rc != 0 {
96+
return Err(rc);
97+
}
98+
let wc_blake2b = unsafe { wc_blake2b.assume_init() };
99+
let blake2b = BLAKE2b { wc_blake2b };
100+
Ok(blake2b)
101+
}
102+
103+
/// Update the BLAKE2b hash with the input data.
104+
///
105+
/// This method may be called several times and then the finalize()
106+
/// method should be called to retrieve the final hash.
107+
///
108+
/// # Parameters
109+
///
110+
/// * `data`: Input data to hash.
111+
///
112+
/// # Returns
113+
///
114+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
115+
/// library error code value.
116+
///
117+
/// # Example
118+
///
119+
/// ```rust
120+
/// use wolfssl_wolfcrypt::blake2::BLAKE2b;
121+
/// let mut blake2b = BLAKE2b::new(64).expect("Error with new()");
122+
/// blake2b.update(&[0u8; 16]).expect("Error with update()");
123+
/// ```
124+
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
125+
let data_size = data.len() as u32;
126+
let rc = unsafe {
127+
sys::wc_Blake2bUpdate(&mut self.wc_blake2b, data.as_ptr(), data_size)
128+
};
129+
if rc != 0 {
130+
return Err(rc);
131+
}
132+
Ok(())
133+
}
134+
135+
/// Compute and retrieve the final BLAKE2b hash value.
136+
///
137+
/// # Parameters
138+
///
139+
/// * `hash`: Output buffer in which to store the computed BLAKE2b hash
140+
/// value. It can be any length.
141+
///
142+
/// # Returns
143+
///
144+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
145+
/// library error code value.
146+
///
147+
/// # Example
148+
///
149+
/// ```rust
150+
/// use wolfssl_wolfcrypt::blake2::BLAKE2b;
151+
/// let mut blake2b = BLAKE2b::new(64).expect("Error with new()");
152+
/// blake2b.update(&[0u8; 16]).expect("Error with update()");
153+
/// let mut hash = [0u8; 64];
154+
/// blake2b.finalize(&mut hash).expect("Error with finalize()");
155+
/// ```
156+
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
157+
let hash_size = hash.len() as u32;
158+
let rc = unsafe {
159+
sys::wc_Blake2bFinal(&mut self.wc_blake2b, hash.as_mut_ptr(), hash_size)
160+
};
161+
if rc != 0 {
162+
return Err(rc);
163+
}
164+
Ok(())
165+
}
166+
}
167+
168+
/// Context for BLAKE2s computation.
169+
#[cfg(blake2s)]
170+
pub struct BLAKE2s {
171+
wc_blake2s: sys::Blake2s,
172+
}
173+
174+
#[cfg(blake2s)]
175+
impl BLAKE2s {
176+
/// Build a new BLAKE2s instance.
177+
///
178+
/// # Parameters
179+
///
180+
/// * `digest_size`: Length of the blake 2 digest to implement.
181+
///
182+
/// # Returns
183+
///
184+
/// Returns either Ok(blake2s) containing the BLAKE2s struct instance or
185+
/// Err(e) containing the wolfSSL library error code value.
186+
///
187+
/// # Example
188+
///
189+
/// ```rust
190+
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
191+
/// let blake2s = BLAKE2s::new(32).expect("Error with new()");
192+
/// ```
193+
pub fn new(digest_size: usize) -> Result<Self, i32> {
194+
let digest_size = digest_size as u32;
195+
let mut wc_blake2s: MaybeUninit<sys::Blake2s> = MaybeUninit::uninit();
196+
let rc = unsafe {
197+
sys::wc_InitBlake2s(wc_blake2s.as_mut_ptr(), digest_size)
198+
};
199+
if rc != 0 {
200+
return Err(rc);
201+
}
202+
let wc_blake2s = unsafe { wc_blake2s.assume_init() };
203+
let blake2s = BLAKE2s { wc_blake2s };
204+
Ok(blake2s)
205+
}
206+
207+
/// Build a new BLAKE2s instance.
208+
///
209+
/// # Parameters
210+
///
211+
/// * `digest_size`: Length of the blake 2 digest to implement.
212+
/// * `key`: Key to use for BLAKE2s operation.
213+
///
214+
/// # Returns
215+
///
216+
/// Returns either Ok(blake2s) containing the BLAKE2s struct instance or
217+
/// Err(e) containing the wolfSSL library error code value.
218+
///
219+
/// # Example
220+
///
221+
/// ```rust
222+
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
223+
/// let key = [42u8; 32];
224+
/// let blake2s = BLAKE2s::new_with_key(32, &key).expect("Error with new()");
225+
/// ```
226+
pub fn new_with_key(digest_size: usize, key: &[u8]) -> Result<Self, i32> {
227+
let digest_size = digest_size as u32;
228+
let mut wc_blake2s: MaybeUninit<sys::Blake2s> = MaybeUninit::uninit();
229+
let key_size = key.len() as u32;
230+
let rc = unsafe {
231+
sys::wc_InitBlake2s_WithKey(wc_blake2s.as_mut_ptr(), digest_size,
232+
key.as_ptr(), key_size)
233+
};
234+
if rc != 0 {
235+
return Err(rc);
236+
}
237+
let wc_blake2s = unsafe { wc_blake2s.assume_init() };
238+
let blake2s = BLAKE2s { wc_blake2s };
239+
Ok(blake2s)
240+
}
241+
242+
/// Update the BLAKE2s hash with the input data.
243+
///
244+
/// This method may be called several times and then the finalize()
245+
/// method should be called to retrieve the final hash.
246+
///
247+
/// # Parameters
248+
///
249+
/// * `data`: Input data to hash.
250+
///
251+
/// # Returns
252+
///
253+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
254+
/// library error code value.
255+
///
256+
/// # Example
257+
///
258+
/// ```rust
259+
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
260+
/// let mut blake2s = BLAKE2s::new(32).expect("Error with new()");
261+
/// blake2s.update(&[0u8; 16]).expect("Error with update()");
262+
/// ```
263+
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
264+
let data_size = data.len() as u32;
265+
let rc = unsafe {
266+
sys::wc_Blake2sUpdate(&mut self.wc_blake2s, data.as_ptr(), data_size)
267+
};
268+
if rc != 0 {
269+
return Err(rc);
270+
}
271+
Ok(())
272+
}
273+
274+
/// Compute and retrieve the final BLAKE2s hash value.
275+
///
276+
/// # Parameters
277+
///
278+
/// * `hash`: Output buffer in which to store the computed BLAKE2s hash
279+
/// value. It can be any length.
280+
///
281+
/// # Returns
282+
///
283+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
284+
/// library error code value.
285+
///
286+
/// # Example
287+
///
288+
/// ```rust
289+
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
290+
/// let mut blake2s = BLAKE2s::new(32).expect("Error with new()");
291+
/// blake2s.update(&[0u8; 16]).expect("Error with update()");
292+
/// let mut hash = [0u8; 64];
293+
/// blake2s.finalize(&mut hash).expect("Error with finalize()");
294+
/// ```
295+
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
296+
let hash_size = hash.len() as u32;
297+
let rc = unsafe {
298+
sys::wc_Blake2sFinal(&mut self.wc_blake2s, hash.as_mut_ptr(), hash_size)
299+
};
300+
if rc != 0 {
301+
return Err(rc);
302+
}
303+
Ok(())
304+
}
305+
}

wrapper/rust/wolfssl-wolfcrypt/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
pub mod sys;
2323

2424
pub mod aes;
25+
pub mod blake2;
2526
pub mod cmac;
2627
pub mod dh;
2728
pub mod ecc;

0 commit comments

Comments
 (0)