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
4 changes: 4 additions & 0 deletions wrapper/rust/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt.rs
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/aes.rs
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/dh.rs
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/ecc.rs
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/hkdf.rs
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/hmac.rs
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/random.rs
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/rsa.rs
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/sha.rs
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_aes.rs
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_dh.rs
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_ecc.rs
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_hkdf.rs
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_hmac.rs
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_random.rs
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_rsa.rs
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_sha.rs
2 changes: 2 additions & 0 deletions wrapper/rust/wolfssl/src/wolfcrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
pub mod aes;
pub mod dh;
pub mod ecc;
pub mod hkdf;
pub mod hmac;
pub mod random;
pub mod rsa;
pub mod sha;
187 changes: 187 additions & 0 deletions wrapper/rust/wolfssl/src/wolfcrypt/hkdf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/*
* 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 HMAC Key
Derivation Function (HKDF) functionality.

It leverages the `wolfssl-sys` crate for low-level FFI bindings, encapsulating
the raw C functions in a memory-safe and easy-to-use Rust API.
*/

use crate::wolfcrypt::hmac::HMAC;
use wolfssl_sys as ws;

/// Perform HKDF-Extract operation.
///
/// This utilizes HMAC to convert `key`, with an optional `salt`, into a
/// derived key which is written to `out`.
///
/// # Parameters
///
/// * `typ`: Hash type, one of `HMAC::TYPE_*`.
/// * `salt`: Salt value (optional).
/// * `key`: Initial Key Material (IKM).
/// * `out`: Output buffer to store HKDF-Extract result. The size of this
/// buffer must match `HMAC::get_hmac_size_by_type(typ)`.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl::wolfcrypt::hkdf::*;
/// use wolfssl::wolfcrypt::hmac::HMAC;
/// use wolfssl_sys as ws;
/// let ikm = b"MyPassword0";
/// let salt = b"12345678ABCDEFGH";
/// let mut extract_out = [0u8; ws::WC_SHA256_DIGEST_SIZE as usize];
/// hkdf_extract(HMAC::TYPE_SHA256, Some(salt), ikm, &mut extract_out).expect("Error with hkdf_extract()");
/// ```
pub fn hkdf_extract(typ: i32, salt: Option<&[u8]>, key: &[u8], out: &mut [u8]) -> Result<(), i32> {
let mut salt_ptr = core::ptr::null();
let mut salt_size = 0u32;
if let Some(salt) = salt {
salt_ptr = salt.as_ptr();
salt_size = salt.len() as u32;
}
let key_size = key.len() as u32;
if out.len() != HMAC::get_hmac_size_by_type(typ)? {
return Err(ws::wolfCrypt_ErrorCodes_BUFFER_E);
}
let rc = unsafe {
ws::wc_HKDF_Extract(typ, salt_ptr, salt_size,
key.as_ptr(), key_size, out.as_mut_ptr())
};
if rc != 0 {
return Err(rc);
}
Ok(())
}

/// Perform HKDF-Expand operation.
///
/// This utilizes HMAC to convert `key`, with optional `info`, into a
/// derived key which is written to `out`.
///
/// # Parameters
///
/// * `typ`: Hash type, one of `HMAC::TYPE_*`.
/// * `key`: Key to use for KDF (typically output of `hkdf_extract()`).
/// * `info`: Optional buffer containing additional info.
/// * `out`: Output buffer to store HKDF-Expand result. The buffer can be
/// any size.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl::wolfcrypt::hkdf::*;
/// use wolfssl::wolfcrypt::hmac::HMAC;
/// use wolfssl_sys as ws;
/// let ikm = b"MyPassword0";
/// let salt = b"12345678ABCDEFGH";
/// let mut extract_out = [0u8; ws::WC_SHA256_DIGEST_SIZE as usize];
/// hkdf_extract(HMAC::TYPE_SHA256, Some(salt), ikm, &mut extract_out).expect("Error with hkdf_extract()");
/// let info = b"0";
/// let mut expand_out = [0u8; 16];
/// hkdf_expand(HMAC::TYPE_SHA256, &extract_out, Some(info), &mut expand_out).expect("Error with hkdf_expand()");
/// ```
pub fn hkdf_expand(typ: i32, key: &[u8], info: Option<&[u8]>, out: &mut [u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
let mut info_ptr = core::ptr::null();
let mut info_size = 0u32;
if let Some(info) = info {
info_ptr = info.as_ptr();
info_size = info.len() as u32;
}
let out_size = out.len() as u32;
let rc = unsafe {
ws::wc_HKDF_Expand(typ, key.as_ptr(), key_size,
info_ptr, info_size, out.as_mut_ptr(), out_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}

/// Perform HMAC Key Derivation Function (HKDF) operation.
///
/// This utilizes HMAC to convert `key`, with an optional `salt` and
/// optional `info` into a derived key which is written to `out`.
///
/// This one-shot function is a combination of `hkdf_extract()` and `hkdf_expand()`.
///
/// # Parameters
///
/// * `typ`: Hash type, one of `HMAC::TYPE_*`.
/// * `key`: Initial Key Material (IKM).
/// * `salt`: Salt value (optional).
/// * `info`: Optional buffer containing additional info.
/// * `out`: Output buffer to store HKDF result. The buffer can be any size.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
///
/// # Example
///
/// ```rust
/// use wolfssl::wolfcrypt::hkdf::*;
/// use wolfssl::wolfcrypt::hmac::HMAC;
/// let ikm = b"MyPassword0";
/// let salt = b"12345678ABCDEFGH";
/// let info = b"0";
/// let mut out = [0u8; 16];
/// hkdf(HMAC::TYPE_SHA256, ikm, Some(salt), Some(info), &mut out).expect("Error with hkdf()");
/// ```
pub fn hkdf(typ: i32, key: &[u8], salt: Option<&[u8]>, info: Option<&[u8]>, out: &mut[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
let mut salt_ptr = core::ptr::null();
let mut salt_size = 0u32;
if let Some(salt) = salt {
salt_ptr = salt.as_ptr();
salt_size = salt.len() as u32;
}
let mut info_ptr = core::ptr::null();
let mut info_size = 0u32;
if let Some(info) = info {
info_ptr = info.as_ptr();
info_size = info.len() as u32;
}
let out_size = out.len() as u32;
let rc = unsafe {
ws::wc_HKDF(typ, key.as_ptr(), key_size, salt_ptr, salt_size,
info_ptr, info_size, out.as_mut_ptr(), out_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
Loading