From 5b8115ed8f6969032c06dfd154682d1239eff4be Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Thu, 23 Oct 2025 09:23:46 -0400 Subject: [PATCH] Rust wrapper: add wolfssl::wolfcrypt::kdf, wolfssl::wolfcrypt::prf --- doc/dox_comments/header_files/hmac.h | 3 +- wrapper/rust/include.am | 4 + wrapper/rust/wolfssl/src/wolfcrypt.rs | 2 + wrapper/rust/wolfssl/src/wolfcrypt/kdf.rs | 191 ++++++++++++++++++++++ wrapper/rust/wolfssl/src/wolfcrypt/prf.rs | 96 +++++++++++ wrapper/rust/wolfssl/tests/test_kdf.rs | 93 +++++++++++ wrapper/rust/wolfssl/tests/test_prf.rs | 31 ++++ 7 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 wrapper/rust/wolfssl/src/wolfcrypt/kdf.rs create mode 100644 wrapper/rust/wolfssl/src/wolfcrypt/prf.rs create mode 100644 wrapper/rust/wolfssl/tests/test_kdf.rs create mode 100644 wrapper/rust/wolfssl/tests/test_prf.rs diff --git a/doc/dox_comments/header_files/hmac.h b/doc/dox_comments/header_files/hmac.h index 1db707a8b..5deade427 100644 --- a/doc/dox_comments/header_files/hmac.h +++ b/doc/dox_comments/header_files/hmac.h @@ -534,8 +534,7 @@ int wc_Tls13_HKDF_Expand_Label_ex( \ingroup HMAC \brief Expand data using HMAC, salt and label and info. TLS v1.3 defines - this function for key derivation. This is the _ex version adding heap hint - and device identifier. + this function for key derivation. \return 0 Returned upon successfully generating a key with the given inputs \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) diff --git a/wrapper/rust/include.am b/wrapper/rust/include.am index cec91e14e..3d9ab8491 100644 --- a/wrapper/rust/include.am +++ b/wrapper/rust/include.am @@ -21,6 +21,8 @@ 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/kdf.rs +EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/prf.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 @@ -29,6 +31,8 @@ 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_kdf.rs +EXTRA_DIST += wrapper/rust/wolfssl/tests/test_prf.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 diff --git a/wrapper/rust/wolfssl/src/wolfcrypt.rs b/wrapper/rust/wolfssl/src/wolfcrypt.rs index a6ae8017b..0bc4ab6e6 100644 --- a/wrapper/rust/wolfssl/src/wolfcrypt.rs +++ b/wrapper/rust/wolfssl/src/wolfcrypt.rs @@ -23,6 +23,8 @@ pub mod dh; pub mod ecc; pub mod hkdf; pub mod hmac; +pub mod kdf; +pub mod prf; pub mod random; pub mod rsa; pub mod sha; diff --git a/wrapper/rust/wolfssl/src/wolfcrypt/kdf.rs b/wrapper/rust/wolfssl/src/wolfcrypt/kdf.rs new file mode 100644 index 000000000..4f2ec1a72 --- /dev/null +++ b/wrapper/rust/wolfssl/src/wolfcrypt/kdf.rs @@ -0,0 +1,191 @@ +/* + * 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 Key Derivation +Function (KDF) 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 RFC 5869 HKDF-Extract operation for TLS v1.3 key derivation. +/// +/// # Parameters +/// +/// * `typ`: Hash type, one of `HMAC::TYPE_*`. +/// * `salt`: Optional Salt value. +/// * `key`: Optional Initial Key Material (IKM). +/// * `out`: Output buffer to store TLS1.3 HKDF-Extract result (generated +/// Pseudo-Random Key (PRK)). 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::hmac::HMAC; +/// use wolfssl::wolfcrypt::kdf::*; +/// use wolfssl_sys as ws; +/// let mut secret = [0u8; ws::WC_SHA256_DIGEST_SIZE as usize]; +/// tls13_hkdf_extract(HMAC::TYPE_SHA256, None, None, &mut secret).expect("Error with tls13_hkdf_extract()"); +/// ``` +pub fn tls13_hkdf_extract(typ: i32, salt: Option<&[u8]>, key: Option<&mut [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 mut ikm_buf = [0u8; ws::WC_MAX_DIGEST_SIZE as usize]; + let mut ikm_ptr = ikm_buf.as_mut_ptr(); + let mut ikm_size = 0u32; + if let Some(key) = key { + if key.len() > 0 { + ikm_ptr = key.as_mut_ptr(); + ikm_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_Tls13_HKDF_Extract(out.as_mut_ptr(), salt_ptr, salt_size, + ikm_ptr, ikm_size, typ) + }; + if rc != 0 { + return Err(rc); + } + Ok(()) +} + +/// Perform RFC 5869 HKDF-Extract operation for TLS v1.3 key derivation. +/// +/// This utilizes HMAC to convert `key`, `label`, and `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 `tls13_hkdf_extract()`). +/// * `protocol`: Buffer containing TLS protocol. +/// * `label`: Buffer containing label. +/// * `info`: Buffer containing additional info. +/// * `out`: Output buffer to store TLS1.3 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::hmac::HMAC; +/// use wolfssl::wolfcrypt::kdf::*; +/// use wolfssl_sys as ws; +/// let hash_hello1 = [ +/// 0x63u8, 0x83, 0x58, 0xab, 0x36, 0xcd, 0x0c, 0xf3, +/// 0x26, 0x07, 0xb5, 0x5f, 0x0b, 0x8b, 0x45, 0xd6, +/// 0x7d, 0x5b, 0x42, 0xdc, 0xa8, 0xaa, 0x06, 0xfb, +/// 0x20, 0xa5, 0xbb, 0x85, 0xdb, 0x54, 0xd8, 0x8b +/// ]; +/// let client_early_traffic_secret = [ +/// 0x20u8, 0x18, 0x72, 0x7c, 0xde, 0x3a, 0x85, 0x17, 0x72, 0xdc, 0xd7, 0x72, +/// 0xb0, 0xfc, 0x45, 0xd0, 0x62, 0xb9, 0xbb, 0x38, 0x69, 0x05, 0x7b, 0xb4, +/// 0x5e, 0x58, 0x5d, 0xed, 0xcd, 0x0b, 0x96, 0xd3 +/// ]; +/// let mut secret = [0u8; ws::WC_SHA256_DIGEST_SIZE as usize]; +/// tls13_hkdf_extract(HMAC::TYPE_SHA256, None, None, &mut secret).expect("Error with tls13_hkdf_extract()"); +/// let protocol_label = b"tls13 "; +/// let ce_traffic_label = b"c e traffic"; +/// let mut expand_out = [0u8; ws::WC_SHA256_DIGEST_SIZE as usize]; +/// tls13_hkdf_expand_label(HMAC::TYPE_SHA256, &secret, +/// protocol_label, ce_traffic_label, +/// &hash_hello1, &mut expand_out).expect("Error with tls13_hkdf_expand_label()"); +/// ``` +pub fn tls13_hkdf_expand_label(typ: i32, key: &[u8], protocol: &[u8], label: &[u8], info: &[u8], out: &mut [u8]) -> Result<(), i32> { + let key_size = key.len() as u32; + let protocol_size = protocol.len() as u32; + let label_size = label.len() as u32; + let info_size = info.len() as u32; + let out_size = out.len() as u32; + let rc = unsafe { + ws::wc_Tls13_HKDF_Expand_Label(out.as_mut_ptr(), out_size, + key.as_ptr(), key_size, protocol.as_ptr(), protocol_size, + label.as_ptr(), label_size, info.as_ptr(), info_size, typ) + }; + if rc != 0 { + return Err(rc); + } + Ok(()) +} + +/// Perform SSH KDF operation. +/// +/// # Parameters +/// +/// * `typ`: Hash type, one of `HMAC::TYPE_*`. +/// * `key_id`: Key ID, typically 'A' through 'F'. +/// * `k`: Initial key. +/// * `h`: Exchange hash. +/// * `session_id`: Unique identifier for the SSH session. +/// * `key`: Output buffer. +/// +/// # Returns +/// +/// Returns either Ok(()) on success or Err(e) containing the wolfSSL +/// library error code value. +/// +/// # Example +/// +/// ```rust +/// use wolfssl::wolfcrypt::hmac::HMAC; +/// use wolfssl::wolfcrypt::kdf::*; +/// let k = [0x42u8; 256]; +/// let h = [0x43u8; 32]; +/// let sid = [0x44u8; 32]; +/// let mut out = [0u8; 16]; +/// ssh_kdf(HMAC::TYPE_SHA256, b'A', &k, &h, &sid, &mut out).expect("Error with ssh_kdf()"); +/// ``` +pub fn ssh_kdf(typ: i32, key_id: u8, k: &[u8], h: &[u8], session_id: &[u8], key: &mut [u8]) -> Result<(), i32> { + let key_size = key.len() as u32; + let k_size = k.len() as u32; + let h_size = h.len() as u32; + let session_size = session_id.len() as u32; + let rc = unsafe { + ws::wc_SSH_KDF(typ as u8, key_id, + key.as_mut_ptr(), key_size, + k.as_ptr(), k_size, h.as_ptr(), h_size, + session_id.as_ptr(), session_size) + }; + if rc != 0 { + return Err(rc); + } + Ok(()) +} diff --git a/wrapper/rust/wolfssl/src/wolfcrypt/prf.rs b/wrapper/rust/wolfssl/src/wolfcrypt/prf.rs new file mode 100644 index 000000000..764041ae1 --- /dev/null +++ b/wrapper/rust/wolfssl/src/wolfcrypt/prf.rs @@ -0,0 +1,96 @@ +/* + * 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 Pseudo Random +Function (PRF) 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 wolfssl_sys as ws; + +pub const PRF_HASH_NONE: i32 = ws::wc_MACAlgorithm_no_mac as i32; +pub const PRF_HASH_MD5: i32 = ws::wc_MACAlgorithm_md5_mac as i32; +pub const PRF_HASH_SHA: i32 = ws::wc_MACAlgorithm_sha_mac as i32; +pub const PRF_HASH_SHA224: i32 = ws::wc_MACAlgorithm_sha224_mac as i32; +pub const PRF_HASH_SHA256: i32 = ws::wc_MACAlgorithm_sha256_mac as i32; +pub const PRF_HASH_SHA384: i32 = ws::wc_MACAlgorithm_sha384_mac as i32; +pub const PRF_HASH_SHA512: i32 = ws::wc_MACAlgorithm_sha512_mac as i32; +pub const PRF_HASH_RMD: i32 = ws::wc_MACAlgorithm_rmd_mac as i32; +pub const PRF_HASH_BLAKE2B: i32 = ws::wc_MACAlgorithm_blake2b_mac as i32; +pub const PRF_HASH_SM3: i32 = ws::wc_MACAlgorithm_sm3_mac as i32; + +/// Pseudo Random Function for MD5, SHA-1, SHA-256, SHA-384, or SHA-512 +/// +/// # Parameters +/// +/// * `secret`: Secret key. +/// * `seed`: Seed. +/// * `hash_type`: PRF Hash type, one of `PRF_HASH_*`. +/// * `heap`: Heap hint. +/// * `dev_id` Device ID to use with crypto callbacks or async hardware. +/// Set to INVALID_DEVID (-2) if not used. +/// * `dout`: Output buffer. +/// +/// # Returns +/// +/// Returns either Ok(()) on success or Err(e) containing the wolfSSL +/// library error code value. +/// +/// # Example +/// +/// ```rust +/// use wolfssl::wolfcrypt::prf::*; +/// use wolfssl_sys as ws; +/// let secret = [0x10u8, 0xbc, 0xb4, 0xa2, 0xe8, 0xdc, 0xf1, 0x9b, 0x4c, +/// 0x51, 0x9c, 0xed, 0x31, 0x1b, 0x51, 0x57, 0x02, 0x3f, +/// 0xa1, 0x7d, 0xfb, 0x0e, 0xf3, 0x4e, 0x8f, 0x6f, 0x71, +/// 0xa3, 0x67, 0x76, 0x6b, 0xfa, 0x5d, 0x46, 0x4a, 0xe8, +/// 0x61, 0x18, 0x81, 0xc4, 0x66, 0xcc, 0x6f, 0x09, 0x99, +/// 0x9d, 0xfc, 0x47]; +/// let seed = [0x73u8, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, +/// 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x0b, 0x46, 0xba, +/// 0x56, 0xbf, 0x1f, 0x5d, 0x99, 0xff, 0xe9, 0xbb, 0x43, +/// 0x01, 0xe7, 0xca, 0x2c, 0x00, 0xdf, 0x9a, 0x39, 0x6e, +/// 0xcf, 0x6d, 0x15, 0x27, 0x4d, 0xf2, 0x93, 0x96, 0x4a, +/// 0x91, 0xde, 0x5c, 0xc0, 0x47, 0x7c, 0xa8, 0xae, 0xcf, +/// 0x5d, 0x93, 0x5f, 0x4c, 0x92, 0xcc, 0x98, 0x5b, 0x43]; +/// let mut out = [0u8; 12]; +/// prf(&secret, &seed, PRF_HASH_SHA384, +/// core::ptr::null_mut(), ws::INVALID_DEVID, +/// &mut out).expect("Error with prf()"); +/// ``` +pub fn prf(secret: &[u8], seed: &[u8], hash_type: i32, heap: *mut ::std::os::raw::c_void, dev_id: i32, dout: &mut [u8]) -> Result<(), i32> { + let secret_size = secret.len() as u32; + let seed_size = seed.len() as u32; + let dout_size = dout.len() as u32; + let rc = unsafe { + ws::wc_PRF(dout.as_mut_ptr(), dout_size, + secret.as_ptr(), secret_size, + seed.as_ptr(), seed_size, + hash_type, heap, dev_id) + }; + if rc != 0 { + return Err(rc); + } + Ok(()) +} diff --git a/wrapper/rust/wolfssl/tests/test_kdf.rs b/wrapper/rust/wolfssl/tests/test_kdf.rs new file mode 100644 index 000000000..bfd657e0e --- /dev/null +++ b/wrapper/rust/wolfssl/tests/test_kdf.rs @@ -0,0 +1,93 @@ +use wolfssl::wolfcrypt::hmac::HMAC; +use wolfssl::wolfcrypt::kdf::*; +use wolfssl_sys as ws; + +#[test] +fn test_tls13_hkdf_extract_expand() { + let hash_hello1 = [ + 0x63u8, 0x83, 0x58, 0xab, 0x36, 0xcd, 0x0c, 0xf3, + 0x26, 0x07, 0xb5, 0x5f, 0x0b, 0x8b, 0x45, 0xd6, + 0x7d, 0x5b, 0x42, 0xdc, 0xa8, 0xaa, 0x06, 0xfb, + 0x20, 0xa5, 0xbb, 0x85, 0xdb, 0x54, 0xd8, 0x8b + ]; + let client_early_traffic_secret = [ + 0x20u8, 0x18, 0x72, 0x7c, 0xde, 0x3a, 0x85, 0x17, 0x72, 0xdc, 0xd7, 0x72, + 0xb0, 0xfc, 0x45, 0xd0, 0x62, 0xb9, 0xbb, 0x38, 0x69, 0x05, 0x7b, 0xb4, + 0x5e, 0x58, 0x5d, 0xed, 0xcd, 0x0b, 0x96, 0xd3 + ]; + + let mut secret = [0u8; ws::WC_SHA256_DIGEST_SIZE as usize]; + + tls13_hkdf_extract(HMAC::TYPE_SHA256, None, None, &mut secret).expect("Error with tls13_hkdf_extract()"); + + let protocol_label = b"tls13 "; + let ce_traffic_label = b"c e traffic"; + let mut expand_out = [0u8; ws::WC_SHA256_DIGEST_SIZE as usize]; + + tls13_hkdf_expand_label(HMAC::TYPE_SHA256, &secret, + protocol_label, ce_traffic_label, + &hash_hello1, &mut expand_out).expect("Error with tls13_hkdf_expand_label()"); + + assert_eq!(expand_out, client_early_traffic_secret); +} + +#[test] +fn test_ssh_kdf() { + let ssh_kdf_set3_k = [ + 0x6Au8, 0xC3, 0x82, 0xEA, 0xAC, 0xA0, 0x93, 0xE1, + 0x25, 0xE2, 0x5C, 0x24, 0xBE, 0xBC, 0x84, 0x64, + 0x0C, 0x11, 0x98, 0x75, 0x07, 0x34, 0x4B, 0x5C, + 0x73, 0x9C, 0xEB, 0x84, 0xA9, 0xE0, 0xB2, 0x22, + 0xB9, 0xA8, 0xB5, 0x1C, 0x83, 0x9E, 0x5E, 0xBE, + 0x49, 0xCF, 0xAD, 0xBF, 0xB3, 0x95, 0x99, 0x76, + 0x4E, 0xD5, 0x22, 0x09, 0x9D, 0xC9, 0x12, 0x75, + 0x19, 0x50, 0xDC, 0x7D, 0xC9, 0x7F, 0xBD, 0xC0, + 0x63, 0x28, 0xB6, 0x8F, 0x22, 0x78, 0x1F, 0xD3, + 0x15, 0xAF, 0x56, 0x80, 0x09, 0xA5, 0x50, 0x9E, + 0x5B, 0x87, 0xA1, 0x1B, 0xF5, 0x27, 0xC0, 0x56, + 0xDA, 0xFF, 0xD8, 0x2A, 0xB6, 0xCB, 0xC2, 0x5C, + 0xCA, 0x37, 0x14, 0x34, 0x59, 0xE7, 0xBC, 0x63, + 0xBC, 0xDE, 0x52, 0x75, 0x7A, 0xDE, 0xB7, 0xDF, + 0x01, 0xCF, 0x12, 0x17, 0x3F, 0x1F, 0xEF, 0x81, + 0x02, 0xEC, 0x5A, 0xB1, 0x42, 0xC2, 0x13, 0xDD, + 0x9D, 0x30, 0x69, 0x62, 0x78, 0xA8, 0xD8, 0xBC, + 0x32, 0xDD, 0xE9, 0x59, 0x2D, 0x28, 0xC0, 0x78, + 0xC6, 0xD9, 0x2B, 0x94, 0x7D, 0x82, 0x5A, 0xCA, + 0xAB, 0x64, 0x94, 0x84, 0x6A, 0x49, 0xDE, 0x24, + 0xB9, 0x62, 0x3F, 0x48, 0x89, 0xE8, 0xAD, 0xC3, + 0x8E, 0x8C, 0x66, 0x9E, 0xFF, 0xEF, 0x17, 0x60, + 0x40, 0xAD, 0x94, 0x5E, 0x90, 0xA7, 0xD3, 0xEE, + 0xC1, 0x5E, 0xFE, 0xEE, 0x78, 0xAE, 0x71, 0x04, + 0x3C, 0x96, 0x51, 0x11, 0x03, 0xA1, 0x6B, 0xA7, + 0xCA, 0xF0, 0xAC, 0xD0, 0x64, 0x2E, 0xFD, 0xBE, + 0x80, 0x99, 0x34, 0xFA, 0xA1, 0xA5, 0xF1, 0xBD, + 0x11, 0x04, 0x36, 0x49, 0xB2, 0x5C, 0xCD, 0x1F, + 0xEE, 0x2E, 0x38, 0x81, 0x5D, 0x4D, 0x5F, 0x5F, + 0xC6, 0xB4, 0x10, 0x29, 0x69, 0xF2, 0x1C, 0x22, + 0xAE, 0x1B, 0x0E, 0x7D, 0x36, 0x03, 0xA5, 0x56, + 0xA1, 0x32, 0x62, 0xFF, 0x62, 0x8D, 0xE2, 0x22 + ]; + let ssh_kdf_set3_h = [ + 0x7B, 0x70, 0x01, 0x18, 0x5E, 0x25, 0x6D, 0x44, + 0x93, 0x44, 0x5F, 0x39, 0xA5, 0x5F, 0xB9, 0x05, + 0xE6, 0x32, 0x1F, 0x4B, 0x5D, 0xD8, 0xBB, 0xF3, + 0x10, 0x0D, 0x51, 0xBA, 0x0B, 0xDA, 0x3D, 0x2D + ]; + let ssh_kdf_set3_sid = [ + 0x7B, 0x70, 0x01, 0x18, 0x5E, 0x25, 0x6D, 0x44, + 0x93, 0x44, 0x5F, 0x39, 0xA5, 0x5F, 0xB9, 0x05, + 0xE6, 0x32, 0x1F, 0x4B, 0x5D, 0xD8, 0xBB, 0xF3, + 0x10, 0x0D, 0x51, 0xBA, 0x0B, 0xDA, 0x3D, 0x2D + ]; + let ssh_kdf_set3_a = [ + 0x81, 0xF0, 0x33, 0x0E, 0xF6, 0xF0, 0x53, 0x61, + 0xB3, 0x82, 0x3B, 0xFD, 0xED, 0x6E, 0x1D, 0xE9 + ]; + + let mut out = [0u8; 16]; + + ssh_kdf(HMAC::TYPE_SHA256, b'A', &ssh_kdf_set3_k, &ssh_kdf_set3_h, + &ssh_kdf_set3_sid, &mut out).expect("Error with ssh_kdf()"); + + assert_eq!(out, ssh_kdf_set3_a); +} diff --git a/wrapper/rust/wolfssl/tests/test_prf.rs b/wrapper/rust/wolfssl/tests/test_prf.rs new file mode 100644 index 000000000..304fdf0ea --- /dev/null +++ b/wrapper/rust/wolfssl/tests/test_prf.rs @@ -0,0 +1,31 @@ +use wolfssl::wolfcrypt::prf::*; +use wolfssl_sys as ws; + +#[test] +fn test_kdf_prf() { + let secret = [0x10u8, 0xbc, 0xb4, 0xa2, 0xe8, 0xdc, 0xf1, 0x9b, 0x4c, + 0x51, 0x9c, 0xed, 0x31, 0x1b, 0x51, 0x57, 0x02, 0x3f, + 0xa1, 0x7d, 0xfb, 0x0e, 0xf3, 0x4e, 0x8f, 0x6f, 0x71, + 0xa3, 0x67, 0x76, 0x6b, 0xfa, 0x5d, 0x46, 0x4a, 0xe8, + 0x61, 0x18, 0x81, 0xc4, 0x66, 0xcc, 0x6f, 0x09, 0x99, + 0x9d, 0xfc, 0x47]; + + let seed = [0x73u8, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, + 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x0b, 0x46, 0xba, + 0x56, 0xbf, 0x1f, 0x5d, 0x99, 0xff, 0xe9, 0xbb, 0x43, + 0x01, 0xe7, 0xca, 0x2c, 0x00, 0xdf, 0x9a, 0x39, 0x6e, + 0xcf, 0x6d, 0x15, 0x27, 0x4d, 0xf2, 0x93, 0x96, 0x4a, + 0x91, 0xde, 0x5c, 0xc0, 0x47, 0x7c, 0xa8, 0xae, 0xcf, + 0x5d, 0x93, 0x5f, 0x4c, 0x92, 0xcc, 0x98, 0x5b, 0x43]; + + let expected = [0xeeu8, 0xcb, 0xb1, 0x30, 0xf2, 0xcd, 0xb3, 0x4a, + 0xbe, 0xda, 0xc1, 0xf6]; + + let mut out = [0u8; 12]; + + prf(&secret, &seed, PRF_HASH_SHA384, + core::ptr::null_mut(), ws::INVALID_DEVID, + &mut out).expect("Error with prf()"); + + assert_eq!(out, expected); +}