Skip to content

Commit a555d52

Browse files
Rust wrapper: add HMAC-BLAKE2[bs] wrappers
1 parent c71a4dd commit a555d52

File tree

3 files changed

+389
-1
lines changed

3 files changed

+389
-1
lines changed

wrapper/rust/wolfssl-wolfcrypt/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ fn scan_cfg() -> Result<()> {
128128

129129
/* blake2 */
130130
check_cfg(&binding, "wc_InitBlake2b", "blake2b");
131+
check_cfg(&binding, "wc_Blake2bHmac", "blake2b_hmac");
131132
check_cfg(&binding, "wc_InitBlake2s", "blake2s");
133+
check_cfg(&binding, "wc_Blake2sHmac", "blake2s_hmac");
132134

133135
/* chacha20_poly1305 */
134136
check_cfg(&binding, "wc_ChaCha20Poly1305_Encrypt", "chacha20_poly1305");

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

Lines changed: 270 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,141 @@ impl BLAKE2b {
167167
}
168168
}
169169

170+
171+
/// Context for HMAC-BLAKE2b computation.
172+
#[cfg(blake2b_hmac)]
173+
pub struct BLAKE2bHmac {
174+
wc_blake2b: sys::Blake2b,
175+
}
176+
177+
#[cfg(blake2b_hmac)]
178+
impl BLAKE2bHmac {
179+
/// Build a new BLAKE2bHmac instance.
180+
///
181+
/// # Parameters
182+
///
183+
/// * `key`: Key to use for HMAC-BLAKE2b computation.
184+
///
185+
/// # Returns
186+
///
187+
/// Returns either Ok(hmac_blake2b) or Err(e) containing the wolfSSL
188+
/// library error code value.
189+
///
190+
/// # Example
191+
///
192+
/// ```rust
193+
/// use wolfssl_wolfcrypt::blake2::BLAKE2bHmac;
194+
/// let key = [42u8, 43, 44];
195+
/// let hmac_blake2b = BLAKE2bHmac::new(&key).expect("Error with new()");
196+
/// ```
197+
pub fn new(key: &[u8]) -> Result<Self, i32> {
198+
let mut wc_blake2b: MaybeUninit<sys::Blake2b> = MaybeUninit::uninit();
199+
let rc = unsafe {
200+
sys::wc_Blake2bHmacInit(wc_blake2b.as_mut_ptr(), key.as_ptr(), key.len())
201+
};
202+
if rc != 0 {
203+
return Err(rc);
204+
}
205+
let wc_blake2b = unsafe { wc_blake2b.assume_init() };
206+
let hmac_blake2b = BLAKE2bHmac { wc_blake2b };
207+
Ok(hmac_blake2b)
208+
}
209+
210+
/// Update the HMAC-BLAKE2b computation with the input data.
211+
///
212+
/// This method may be called several times and then the finalize()
213+
/// method should be called to retrieve the final MAC.
214+
///
215+
/// # Parameters
216+
///
217+
/// * `data`: Input data to hash.
218+
///
219+
/// # Returns
220+
///
221+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
222+
/// library error code value.
223+
///
224+
/// # Example
225+
///
226+
/// ```rust
227+
/// use wolfssl_wolfcrypt::blake2::BLAKE2bHmac;
228+
/// let key = [42u8, 43, 44];
229+
/// let mut hmac_blake2b = BLAKE2bHmac::new(&key).expect("Error with new()");
230+
/// let data = [33u8, 34, 35];
231+
/// hmac_blake2b.update(&data).expect("Error with update()");
232+
/// ```
233+
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
234+
let rc = unsafe {
235+
sys::wc_Blake2bHmacUpdate(&mut self.wc_blake2b, data.as_ptr(), data.len())
236+
};
237+
if rc != 0 {
238+
return Err(rc);
239+
}
240+
Ok(())
241+
}
242+
243+
/// Compute and retrieve the final HMAC-BLAKE2b MAC.
244+
///
245+
/// # Parameters
246+
///
247+
/// * `key`: Key to use for HMAC-BLAKE2b computation.
248+
/// * `mac`: Output buffer in which to store the computed HMAC-BLAKE2b MAC.
249+
/// It must be 64 bytes long.
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::BLAKE2bHmac;
260+
/// let key = [42u8, 43, 44];
261+
/// let mut hmac_blake2b = BLAKE2bHmac::new(&key).expect("Error with new()");
262+
/// let data = [33u8, 34, 35];
263+
/// hmac_blake2b.update(&data).expect("Error with update()");
264+
/// let mut mac = [0u8; 64];
265+
/// hmac_blake2b.finalize(&key, &mut mac).expect("Error with finalize()");
266+
/// ```
267+
pub fn finalize(&mut self, key: &[u8], mac: &mut [u8]) -> Result<(), i32> {
268+
let rc = unsafe {
269+
sys::wc_Blake2bHmacFinal(&mut self.wc_blake2b,
270+
key.as_ptr(), key.len(), mac.as_mut_ptr(), mac.len())
271+
};
272+
if rc != 0 {
273+
return Err(rc);
274+
}
275+
Ok(())
276+
}
277+
278+
/// Compute the HMAC-BLAKE2b message authentication code of the given
279+
/// input data using the given key (one-shot API).
280+
///
281+
/// # Parameters
282+
///
283+
/// * `data`: Input data to create MAC from.
284+
/// * `key`: Key to use for MAC creation.
285+
/// * `out`: Buffer in which to store the computed MAC.
286+
///
287+
/// # Returns
288+
///
289+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
290+
/// library error code value.
291+
#[cfg(blake2b_hmac)]
292+
pub fn hmac(data: &[u8], key: &[u8], out: &mut [u8]) -> Result<(), i32> {
293+
let rc = unsafe {
294+
sys::wc_Blake2bHmac(data.as_ptr(), data.len(), key.as_ptr(),
295+
key.len(), out.as_mut_ptr(), out.len())
296+
};
297+
if rc != 0 {
298+
return Err(rc);
299+
}
300+
Ok(())
301+
}
302+
}
303+
304+
170305
/// Context for BLAKE2s computation.
171306
#[cfg(blake2s)]
172307
pub struct BLAKE2s {
@@ -291,7 +426,7 @@ impl BLAKE2s {
291426
/// use wolfssl_wolfcrypt::blake2::BLAKE2s;
292427
/// let mut blake2s = BLAKE2s::new(32).expect("Error with new()");
293428
/// blake2s.update(&[0u8; 16]).expect("Error with update()");
294-
/// let mut hash = [0u8; 64];
429+
/// let mut hash = [0u8; 32];
295430
/// blake2s.finalize(&mut hash).expect("Error with finalize()");
296431
/// ```
297432
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
@@ -305,3 +440,137 @@ impl BLAKE2s {
305440
Ok(())
306441
}
307442
}
443+
444+
445+
/// Context for HMAC-BLAKE2s computation.
446+
#[cfg(blake2s_hmac)]
447+
pub struct BLAKE2sHmac {
448+
wc_blake2s: sys::Blake2s,
449+
}
450+
451+
#[cfg(blake2s_hmac)]
452+
impl BLAKE2sHmac {
453+
/// Build a new BLAKE2sHmac instance.
454+
///
455+
/// # Parameters
456+
///
457+
/// * `key`: Key to use for HMAC-BLAKE2s computation.
458+
///
459+
/// # Returns
460+
///
461+
/// Returns either Ok(hmac_blake2s) or Err(e) containing the wolfSSL
462+
/// library error code value.
463+
///
464+
/// # Example
465+
///
466+
/// ```rust
467+
/// use wolfssl_wolfcrypt::blake2::BLAKE2sHmac;
468+
/// let key = [42u8, 43, 44];
469+
/// let hmac_blake2s = BLAKE2sHmac::new(&key).expect("Error with new()");
470+
/// ```
471+
pub fn new(key: &[u8]) -> Result<Self, i32> {
472+
let mut wc_blake2s: MaybeUninit<sys::Blake2s> = MaybeUninit::uninit();
473+
let rc = unsafe {
474+
sys::wc_Blake2sHmacInit(wc_blake2s.as_mut_ptr(), key.as_ptr(), key.len())
475+
};
476+
if rc != 0 {
477+
return Err(rc);
478+
}
479+
let wc_blake2s = unsafe { wc_blake2s.assume_init() };
480+
let hmac_blake2s = BLAKE2sHmac { wc_blake2s };
481+
Ok(hmac_blake2s)
482+
}
483+
484+
/// Update the HMAC-BLAKE2s computation with the input data.
485+
///
486+
/// This method may be called several times and then the finalize()
487+
/// method should be called to retrieve the final MAC.
488+
///
489+
/// # Parameters
490+
///
491+
/// * `data`: Input data to hash.
492+
///
493+
/// # Returns
494+
///
495+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
496+
/// library error code value.
497+
///
498+
/// # Example
499+
///
500+
/// ```rust
501+
/// use wolfssl_wolfcrypt::blake2::BLAKE2sHmac;
502+
/// let key = [42u8, 43, 44];
503+
/// let mut hmac_blake2s = BLAKE2sHmac::new(&key).expect("Error with new()");
504+
/// let data = [33u8, 34, 35];
505+
/// hmac_blake2s.update(&data).expect("Error with update()");
506+
/// ```
507+
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
508+
let rc = unsafe {
509+
sys::wc_Blake2sHmacUpdate(&mut self.wc_blake2s, data.as_ptr(), data.len())
510+
};
511+
if rc != 0 {
512+
return Err(rc);
513+
}
514+
Ok(())
515+
}
516+
517+
/// Compute and retrieve the final HMAC-BLAKE2s MAC.
518+
///
519+
/// # Parameters
520+
///
521+
/// * `key`: Key to use for HMAC-BLAKE2s computation.
522+
/// * `mac`: Output buffer in which to store the computed HMAC-BLAKE2s MAC.
523+
/// It must be 32 bytes long.
524+
///
525+
/// # Returns
526+
///
527+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
528+
/// library error code value.
529+
///
530+
/// # Example
531+
///
532+
/// ```rust
533+
/// use wolfssl_wolfcrypt::blake2::BLAKE2sHmac;
534+
/// let key = [42u8, 43, 44];
535+
/// let mut hmac_blake2s = BLAKE2sHmac::new(&key).expect("Error with new()");
536+
/// let data = [33u8, 34, 35];
537+
/// hmac_blake2s.update(&data).expect("Error with update()");
538+
/// let mut mac = [0u8; 32];
539+
/// hmac_blake2s.finalize(&key, &mut mac).expect("Error with finalize()");
540+
/// ```
541+
pub fn finalize(&mut self, key: &[u8], mac: &mut [u8]) -> Result<(), i32> {
542+
let rc = unsafe {
543+
sys::wc_Blake2sHmacFinal(&mut self.wc_blake2s,
544+
key.as_ptr(), key.len(), mac.as_mut_ptr(), mac.len())
545+
};
546+
if rc != 0 {
547+
return Err(rc);
548+
}
549+
Ok(())
550+
}
551+
552+
/// Compute the HMAC-BLAKE2s message authentication code of the given
553+
/// input data using the given key (one-shot API).
554+
///
555+
/// # Parameters
556+
///
557+
/// * `data`: Input data to create MAC from.
558+
/// * `key`: Key to use for MAC creation.
559+
/// * `out`: Buffer in which to store the computed MAC.
560+
///
561+
/// # Returns
562+
///
563+
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
564+
/// library error code value.
565+
#[cfg(blake2s_hmac)]
566+
pub fn hmac(data: &[u8], key: &[u8], out: &mut [u8]) -> Result<(), i32> {
567+
let rc = unsafe {
568+
sys::wc_Blake2sHmac(data.as_ptr(), data.len(), key.as_ptr(),
569+
key.len(), out.as_mut_ptr(), out.len())
570+
};
571+
if rc != 0 {
572+
return Err(rc);
573+
}
574+
Ok(())
575+
}
576+
}

0 commit comments

Comments
 (0)