/* * Copyright (C) 2006-2026 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. */ use crate::sys; #[cfg(all(hmac, kdf_tls13))] use crate::hmac::HMAC; #[cfg(kdf_srtp)] pub const SRTP_LABEL_ENCRYPTION: u8 = sys::WC_SRTP_LABEL_ENCRYPTION as u8; #[cfg(kdf_srtp)] pub const SRTP_LABEL_MSG_AUTH: u8 = sys::WC_SRTP_LABEL_MSG_AUTH as u8; #[cfg(kdf_srtp)] pub const SRTP_LABEL_SALT: u8 = sys::WC_SRTP_LABEL_SALT as u8; #[cfg(kdf_srtp)] pub const SRTCP_LABEL_ENCRYPTION: u8 = sys::WC_SRTCP_LABEL_ENCRYPTION as u8; #[cfg(kdf_srtp)] pub const SRTCP_LABEL_MSG_AUTH: u8 = sys::WC_SRTCP_LABEL_MSG_AUTH as u8; #[cfg(kdf_srtp)] pub const SRTCP_LABEL_SALT: u8 = sys::WC_SRTCP_LABEL_SALT as u8; #[cfg(kdf_srtp)] pub const SRTP_LABEL_HDR_ENCRYPTION: u8 = sys::WC_SRTP_LABEL_HDR_ENCRYPTION as u8; #[cfg(kdf_srtp)] pub const SRTP_LABEL_HDR_SALT: u8 = sys::WC_SRTP_LABEL_HDR_SALT as u8; #[cfg(kdf_srtp)] pub const SRTP_INDEX_LEN: usize = sys::WC_SRTP_INDEX_LEN as usize; #[cfg(kdf_srtp)] pub const SRTCP_INDEX_LEN: usize = sys::WC_SRTCP_INDEX_LEN as usize; /// Implement Password Based Key Derivation Function 2 (PBKDF2) converting an /// input password with a concatenated salt into a more secure key which is /// written to the `out` buffer. /// /// # Parameters /// /// * `password`: Password to use for key derivation. /// * `salt`: Salt value to use for key derivation. /// * `iterations`: Number of times to process the hash. /// * `typ`: Hash type, one of `HMAC::TYPE_*`. /// * `out`: Output buffer in which to store the generated key. /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(all(hmac, kdf_pbkdf2))] /// { /// use wolfssl_wolfcrypt::kdf::pbkdf2; /// use wolfssl_wolfcrypt::hmac::HMAC; /// let password = b"passwordpassword"; /// let salt = [0x78u8, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06]; /// let iterations = 2048; /// let expected_key = [ /// 0x43u8, 0x6d, 0xb5, 0xe8, 0xd0, 0xfb, 0x3f, 0x35, 0x42, 0x48, 0x39, 0xbc, /// 0x2d, 0xd4, 0xf9, 0x37, 0xd4, 0x95, 0x16, 0xa7, 0x2a, 0x9a, 0x21, 0xd1 /// ]; /// let mut keyout = [0u8; 24]; /// pbkdf2(password, &salt, iterations, HMAC::TYPE_SHA256, &mut keyout).expect("Error with pbkdf2()"); /// assert_eq!(keyout, expected_key); /// } /// ``` #[cfg(kdf_pbkdf2)] pub fn pbkdf2(password: &[u8], salt: &[u8], iterations: i32, typ: i32, out: &mut [u8]) -> Result<(), i32> { pbkdf2_ex(password, salt, iterations, typ, None, None, out) } /// Implement Password Based Key Derivation Function 2 (PBKDF2) converting an /// input password with a concatenated salt into a more secure key which is /// written to the `out` buffer. /// This version allows optional heap hint and device ID parameters. /// /// # Parameters /// /// * `password`: Password to use for key derivation. /// * `salt`: Salt value to use for key derivation. /// * `iterations`: Number of times to process the hash. /// * `typ`: Hash type, one of `HMAC::TYPE_*`. /// * `heap`: Optional heap hint. /// * `dev_id` Optional device ID to use with crypto callbacks or async hardware. /// * `out`: Output buffer in which to store the generated key. /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(all(hmac, kdf_pbkdf2))] /// { /// use wolfssl_wolfcrypt::kdf::pbkdf2_ex; /// use wolfssl_wolfcrypt::hmac::HMAC; /// let password = b"passwordpassword"; /// let salt = [0x78u8, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06]; /// let iterations = 2048; /// let expected_key = [ /// 0x43u8, 0x6d, 0xb5, 0xe8, 0xd0, 0xfb, 0x3f, 0x35, 0x42, 0x48, 0x39, 0xbc, /// 0x2d, 0xd4, 0xf9, 0x37, 0xd4, 0x95, 0x16, 0xa7, 0x2a, 0x9a, 0x21, 0xd1 /// ]; /// let mut keyout = [0u8; 24]; /// pbkdf2_ex(password, &salt, iterations, HMAC::TYPE_SHA256, None, None, &mut keyout).expect("Error with pbkdf2_ex()"); /// assert_eq!(keyout, expected_key); /// } /// ``` #[cfg(kdf_pbkdf2)] pub fn pbkdf2_ex(password: &[u8], salt: &[u8], iterations: i32, typ: i32, heap: Option<*mut core::ffi::c_void>, dev_id: Option, out: &mut [u8]) -> Result<(), i32> { let password_size = crate::buffer_len_to_i32(password.len())?; let salt_size = crate::buffer_len_to_i32(salt.len())?; let out_size = crate::buffer_len_to_i32(out.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), }; let dev_id = match dev_id { Some(dev_id) => dev_id, None => sys::INVALID_DEVID, }; let rc = unsafe { sys::wc_PBKDF2_ex(out.as_mut_ptr(), password.as_ptr(), password_size, salt.as_ptr(), salt_size, iterations, out_size, typ, heap, dev_id) }; if rc != 0 { return Err(rc); } Ok(()) } /// This function implements the Password Based Key Derivation Function /// (PBKDF) described in RFC 7292 Appendix B. This function converts an input /// password with a concatenated salt into a more secure key, which it stores /// in `out`. It allows the user to select any of the supported HMAC hash /// functions, including: WC_MD5, WC_SHA, WC_SHA256, WC_SHA384, WC_SHA512, /// WC_SHA3_224, WC_SHA3_256, WC_SHA3_384 or WC_SHA3_512. /// /// # Parameters /// /// * `password`: Password to use for key derivation. /// * `salt`: Salt value to use for key derivation. /// * `iterations`: Number of times to process the hash. /// * `typ`: Hash type, one of `HMAC::TYPE_*`. /// * `id`: Byte identifier indicating the purpose of key generation. It is /// used to diversify the key output, and should be assigned as follows: /// ID=1: pseudorandom bits are to be used as key material for performing /// encryption or decryption. ID=2: pseudorandom bits are to be used an IV /// (Initial Value) for encryption or decryption. ID=3: pseudorandom bits /// are to be used as an integrity key for MACing. /// * `out`: Output buffer in which to store the generated key. /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(all(hmac, kdf_pkcs12))] /// { /// use wolfssl_wolfcrypt::kdf::pkcs12_pbkdf; /// use wolfssl_wolfcrypt::hmac::HMAC; /// let password = [0x00u8, 0x73, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x67, 0x00, 0x00]; /// let salt = [0x0au8, 0x58, 0xCF, 0x64, 0x53, 0x0d, 0x82, 0x3f]; /// let expected_key = [ /// 0x27u8, 0xE9, 0x0D, 0x7E, 0xD5, 0xA1, 0xC4, 0x11, /// 0xBA, 0x87, 0x8B, 0xC0, 0x90, 0xF5, 0xCE, 0xBE, /// 0x5E, 0x9D, 0x5F, 0xE3, 0xD6, 0x2B, 0x73, 0xAA /// ]; /// let iterations = 1; /// let mut keyout = [0u8; 24]; /// pkcs12_pbkdf(&password, &salt, iterations, HMAC::TYPE_SHA256, 1, &mut keyout).expect("Error with pkcs12_pbkdf()"); /// assert_eq!(keyout, expected_key); /// } /// ``` #[cfg(kdf_pkcs12)] pub fn pkcs12_pbkdf(password: &[u8], salt: &[u8], iterations: i32, typ: i32, id: i32, out: &mut [u8]) -> Result<(), i32> { pkcs12_pbkdf_ex(password, salt, iterations, typ, id, None, out) } /// This function implements the Password Based Key Derivation Function /// (PBKDF) described in RFC 7292 Appendix B. This function converts an input /// password with a concatenated salt into a more secure key, which it stores /// in `out`. It allows the user to select any of the supported HMAC hash /// functions, including: WC_MD5, WC_SHA, WC_SHA256, WC_SHA384, WC_SHA512, /// WC_SHA3_224, WC_SHA3_256, WC_SHA3_384 or WC_SHA3_512. /// This version allows an optional heap hint parameter. /// /// # Parameters /// /// * `password`: Password to use for key derivation. /// * `salt`: Salt value to use for key derivation. /// * `iterations`: Number of times to process the hash. /// * `typ`: Hash type, one of `HMAC::TYPE_*`. /// * `id`: Byte identifier indicating the purpose of key generation. It is /// used to diversify the key output, and should be assigned as follows: /// ID=1: pseudorandom bits are to be used as key material for performing /// encryption or decryption. ID=2: pseudorandom bits are to be used an IV /// (Initial Value) for encryption or decryption. ID=3: pseudorandom bits /// are to be used as an integrity key for MACing. /// * `heap`: Optional heap hint. /// * `out`: Output buffer in which to store the generated key. /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(all(hmac, kdf_pkcs12))] /// { /// use wolfssl_wolfcrypt::kdf::pkcs12_pbkdf_ex; /// use wolfssl_wolfcrypt::hmac::HMAC; /// let password = [0x00u8, 0x73, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x67, 0x00, 0x00]; /// let salt = [0x0au8, 0x58, 0xCF, 0x64, 0x53, 0x0d, 0x82, 0x3f]; /// let expected_key = [ /// 0x27u8, 0xE9, 0x0D, 0x7E, 0xD5, 0xA1, 0xC4, 0x11, /// 0xBA, 0x87, 0x8B, 0xC0, 0x90, 0xF5, 0xCE, 0xBE, /// 0x5E, 0x9D, 0x5F, 0xE3, 0xD6, 0x2B, 0x73, 0xAA /// ]; /// let iterations = 1; /// let mut keyout = [0u8; 24]; /// pkcs12_pbkdf_ex(&password, &salt, iterations, HMAC::TYPE_SHA256, 1, None, &mut keyout).expect("Error with pkcs12_pbkdf_ex()"); /// assert_eq!(keyout, expected_key); /// } /// ``` #[cfg(kdf_pkcs12)] pub fn pkcs12_pbkdf_ex(password: &[u8], salt: &[u8], iterations: i32, typ: i32, id: i32, heap: Option<*mut core::ffi::c_void>, out: &mut [u8]) -> Result<(), i32> { let password_size = crate::buffer_len_to_i32(password.len())?; let salt_size = crate::buffer_len_to_i32(salt.len())?; let out_size = crate::buffer_len_to_i32(out.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), }; let rc = unsafe { sys::wc_PKCS12_PBKDF_ex(out.as_mut_ptr(), password.as_ptr(), password_size, salt.as_ptr(), salt_size, iterations, out_size, typ, id, heap) }; if rc != 0 { return Err(rc); } Ok(()) } /// 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 /// #[cfg(all(hmac, kdf_tls13))] /// { /// use wolfssl_wolfcrypt::hmac::HMAC; /// use wolfssl_wolfcrypt::kdf::*; /// use wolfssl_wolfcrypt::sha::SHA256; /// let mut secret = [0u8; SHA256::DIGEST_SIZE]; /// tls13_hkdf_extract(HMAC::TYPE_SHA256, None, None, &mut secret).expect("Error with tls13_hkdf_extract()"); /// } /// ``` #[cfg(all(hmac, kdf_tls13))] pub fn tls13_hkdf_extract(typ: i32, salt: Option<&[u8]>, key: Option<&mut [u8]>, out: &mut [u8]) -> Result<(), i32> { tls13_hkdf_extract_ex(typ, salt, key, out, None, None) } /// Perform RFC 5869 HKDF-Extract operation for TLS v1.3 key derivation (with /// optional heap and device ID). /// /// # 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)`. /// * `heap`: Optional heap hint. /// * `dev_id` Optional device ID to use with crypto callbacks or async hardware. /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(all(hmac, kdf_tls13))] /// { /// use wolfssl_wolfcrypt::hmac::HMAC; /// use wolfssl_wolfcrypt::kdf::*; /// use wolfssl_wolfcrypt::sha::SHA256; /// let mut secret = [0u8; SHA256::DIGEST_SIZE]; /// tls13_hkdf_extract_ex(HMAC::TYPE_SHA256, None, None, &mut secret, None, None).expect("Error with tls13_hkdf_extract_ex()"); /// } /// ``` #[cfg(all(hmac, kdf_tls13))] pub fn tls13_hkdf_extract_ex(typ: i32, salt: Option<&[u8]>, key: Option<&mut [u8]>, out: &mut [u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> 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 = crate::buffer_len_to_u32(salt.len())?; } let mut ikm_buf = [0u8; sys::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 && !key.is_empty() { ikm_ptr = key.as_mut_ptr(); ikm_size = crate::buffer_len_to_u32(key.len())?; } if out.len() != HMAC::get_hmac_size_by_type(typ)? { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), }; let dev_id = match dev_id { Some(dev_id) => dev_id, None => sys::INVALID_DEVID, }; let rc = unsafe { sys::wc_Tls13_HKDF_Extract_ex(out.as_mut_ptr(), salt_ptr, salt_size, ikm_ptr, ikm_size, typ, heap, dev_id) }; if rc != 0 { return Err(rc); } Ok(()) } /// Perform RFC 5869 HKDF-Expand 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 /// #[cfg(all(hmac, kdf_tls13))] /// { /// use wolfssl_wolfcrypt::hmac::HMAC; /// use wolfssl_wolfcrypt::kdf::*; /// use wolfssl_wolfcrypt::sha::SHA256; /// 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; SHA256::DIGEST_SIZE]; /// 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; SHA256::DIGEST_SIZE]; /// 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()"); /// } /// ``` #[cfg(all(hmac, kdf_tls13))] pub fn tls13_hkdf_expand_label(typ: i32, key: &[u8], protocol: &[u8], label: &[u8], info: &[u8], out: &mut [u8]) -> Result<(), i32> { tls13_hkdf_expand_label_ex(typ, key, protocol, label, info, out, None, None) } /// Perform RFC 5869 HKDF-Expand operation for TLS v1.3 key derivation (with /// optional heap and device ID). /// /// 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. /// * `heap`: Optional heap hint. /// * `dev_id` Optional device ID to use with crypto callbacks or async hardware. /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(all(hmac, kdf_tls13))] /// { /// use wolfssl_wolfcrypt::hmac::HMAC; /// use wolfssl_wolfcrypt::kdf::*; /// use wolfssl_wolfcrypt::sha::SHA256; /// 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; SHA256::DIGEST_SIZE]; /// 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; SHA256::DIGEST_SIZE]; /// tls13_hkdf_expand_label_ex(HMAC::TYPE_SHA256, &secret, /// protocol_label, ce_traffic_label, /// &hash_hello1, &mut expand_out, None, None).expect("Error with tls13_hkdf_expand_label_ex()"); /// } /// ``` #[cfg(all(hmac, kdf_tls13))] #[allow(clippy::too_many_arguments)] pub fn tls13_hkdf_expand_label_ex(typ: i32, key: &[u8], protocol: &[u8], label: &[u8], info: &[u8], out: &mut [u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result<(), i32> { let key_size = crate::buffer_len_to_u32(key.len())?; let protocol_size = crate::buffer_len_to_u32(protocol.len())?; let label_size = crate::buffer_len_to_u32(label.len())?; let info_size = crate::buffer_len_to_u32(info.len())?; let out_size = crate::buffer_len_to_u32(out.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), }; let dev_id = match dev_id { Some(dev_id) => dev_id, None => sys::INVALID_DEVID, }; let rc = unsafe { sys::wc_Tls13_HKDF_Expand_Label_ex(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, heap, dev_id) }; 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 /// #[cfg(kdf_ssh)] /// { /// 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()"); /// } /// ``` #[cfg(kdf_ssh)] pub fn ssh_kdf(typ: i32, key_id: u8, k: &[u8], h: &[u8], session_id: &[u8], key: &mut [u8]) -> Result<(), i32> { let key_size = crate::buffer_len_to_u32(key.len())?; let k_size = crate::buffer_len_to_u32(k.len())?; let h_size = crate::buffer_len_to_u32(h.len())?; let session_size = crate::buffer_len_to_u32(session_id.len())?; let rc = unsafe { sys::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(()) } /// Perform SRTP KDF algorithm to derive keys. /// /// # Parameters /// /// * `key`: Key to use with encryption. /// * `salt`: Random non-secret value. /// * `kdr_index`: Key derivation rate: -1 for 0, otherwise KDR = 2^kdr_index. /// * `idx`: Index value to XOR in. /// * `key1`: Output buffer for first key (label of 0x00). /// * `key2`: Output buffer for second key (label of 0x01). /// * `key3`: Output buffer for third key (label of 0x02). /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(kdf_srtp)] /// { /// use wolfssl_wolfcrypt::kdf::*; /// let key = [0xc4u8, 0x80, 0x9f, 0x6d, 0x36, 0x98, 0x88, 0x72, /// 0x8e, 0x26, 0xad, 0xb5, 0x32, 0x12, 0x98, 0x90]; /// let salt = [0x0eu8, 0x23, 0x00, 0x6c, 0x6c, 0x04, 0x4f, 0x56, /// 0x62, 0x40, 0x0e, 0x9d, 0x1b, 0xd6]; /// let index = [0x48u8, 0x71, 0x65, 0x64, 0x9c, 0xca]; /// let mut key_e = [0u8; 16]; /// let mut key_a = [0u8; 20]; /// let mut key_s = [0u8; 14]; /// srtp_kdf(&key, &salt, -1, &index, &mut key_e, &mut key_a, &mut key_s).expect("Error with srtp_kdf()"); /// } /// ``` #[cfg(kdf_srtp)] pub fn srtp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8; SRTP_INDEX_LEN], key1: &mut [u8], key2: &mut [u8], key3: &mut [u8]) -> Result<(), i32> { let key_size = crate::buffer_len_to_u32(key.len())?; let salt_size = crate::buffer_len_to_u32(salt.len())?; let key1_size = crate::buffer_len_to_u32(key1.len())?; let key2_size = crate::buffer_len_to_u32(key2.len())?; let key3_size = crate::buffer_len_to_u32(key3.len())?; let rc = unsafe { sys::wc_SRTP_KDF(key.as_ptr(), key_size, salt.as_ptr(), salt_size, kdr_index, idx.as_ptr(), key1.as_mut_ptr(), key1_size, key2.as_mut_ptr(), key2_size, key3.as_mut_ptr(), key3_size) }; if rc != 0 { return Err(rc); } Ok(()) } /// Perform SRTP KDF algorithm to derive a key with a given label. /// /// # Parameters /// /// * `key`: Key to use with encryption. /// * `salt`: Random non-secret value. /// * `kdr_index`: Key derivation rate: -1 for 0, otherwise KDR = 2^kdr_index. /// * `idx`: Index value to XOR in. /// * `label`: Label: typically one of `SRTP_LABEL_*`. /// * `keyout`: Output buffer for generated key. /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(kdf_srtp)] /// { /// use wolfssl_wolfcrypt::kdf::*; /// let key = [0xc4u8, 0x80, 0x9f, 0x6d, 0x36, 0x98, 0x88, 0x72, /// 0x8e, 0x26, 0xad, 0xb5, 0x32, 0x12, 0x98, 0x90]; /// let salt = [0x0eu8, 0x23, 0x00, 0x6c, 0x6c, 0x04, 0x4f, 0x56, /// 0x62, 0x40, 0x0e, 0x9d, 0x1b, 0xd6]; /// let index = [0x48u8, 0x71, 0x65, 0x64, 0x9c, 0xca]; /// let mut key_a = [0u8; 20]; /// srtp_kdf_label(&key, &salt, -1, &index, SRTP_LABEL_MSG_AUTH, &mut key_a).expect("Error with srtp_kdf_label()"); /// } /// ``` #[cfg(kdf_srtp)] pub fn srtp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8; SRTP_INDEX_LEN], label: u8, keyout: &mut [u8]) -> Result<(), i32> { let key_size = crate::buffer_len_to_u32(key.len())?; let salt_size = crate::buffer_len_to_u32(salt.len())?; let keyout_size = crate::buffer_len_to_u32(keyout.len())?; let rc = unsafe { sys::wc_SRTP_KDF_label(key.as_ptr(), key_size, salt.as_ptr(), salt_size, kdr_index, idx.as_ptr(), label, keyout.as_mut_ptr(), keyout_size) }; if rc != 0 { return Err(rc); } Ok(()) } /// Perform SRTCP KDF algorithm to derive keys. /// /// # Parameters /// /// * `key`: Key to use with encryption. Key length must be 16, 24, or 32. /// * `salt`: Random non-secret value. /// * `kdr_index`: Key derivation rate: -1 for 0, otherwise KDR = 2^kdr_index. /// * `idx`: Index value to XOR in. /// * `key1`: Output buffer for first key (label of 0x00). /// * `key2`: Output buffer for second key (label of 0x01). /// * `key3`: Output buffer for third key (label of 0x02). /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(kdf_srtp)] /// { /// use wolfssl_wolfcrypt::kdf::*; /// let key = [0xc4u8, 0x80, 0x9f, 0x6d, 0x36, 0x98, 0x88, 0x72, /// 0x8e, 0x26, 0xad, 0xb5, 0x32, 0x12, 0x98, 0x90]; /// let salt = [0x0eu8, 0x23, 0x00, 0x6c, 0x6c, 0x04, 0x4f, 0x56, /// 0x62, 0x40, 0x0e, 0x9d, 0x1b, 0xd6]; /// let index = [0x48u8, 0x71, 0x65, 0x64]; /// let mut key_e = [0u8; 16]; /// let mut key_a = [0u8; 20]; /// let mut key_s = [0u8; 14]; /// srtcp_kdf(&key, &salt, -1, &index, &mut key_e, &mut key_a, &mut key_s).expect("Error with srtcp_kdf()"); /// } /// ``` #[cfg(kdf_srtp)] pub fn srtcp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8; SRTCP_INDEX_LEN], key1: &mut [u8], key2: &mut [u8], key3: &mut [u8]) -> Result<(), i32> { let key_size = crate::buffer_len_to_u32(key.len())?; let salt_size = crate::buffer_len_to_u32(salt.len())?; let key1_size = crate::buffer_len_to_u32(key1.len())?; let key2_size = crate::buffer_len_to_u32(key2.len())?; let key3_size = crate::buffer_len_to_u32(key3.len())?; let rc = unsafe { sys::wc_SRTCP_KDF(key.as_ptr(), key_size, salt.as_ptr(), salt_size, kdr_index, idx.as_ptr(), key1.as_mut_ptr(), key1_size, key2.as_mut_ptr(), key2_size, key3.as_mut_ptr(), key3_size) }; if rc != 0 { return Err(rc); } Ok(()) } /// Perform SRTCP KDF algorithm to derive a key with a given label. /// /// # Parameters /// /// * `key`: Key to use with encryption. /// * `salt`: Random non-secret value. /// * `kdr_index`: Key derivation rate: -1 for 0, otherwise KDR = 2^kdr_index. /// * `idx`: Index value to XOR in. /// * `label`: Label: typically one of `SRTCP_LABEL_*`. /// * `keyout`: Output buffer for generated key. /// /// # Returns /// /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. /// /// # Example /// /// ```rust /// #[cfg(kdf_srtp)] /// { /// use wolfssl_wolfcrypt::kdf::*; /// let key = [0xc4u8, 0x80, 0x9f, 0x6d, 0x36, 0x98, 0x88, 0x72, /// 0x8e, 0x26, 0xad, 0xb5, 0x32, 0x12, 0x98, 0x90]; /// let salt = [0x0eu8, 0x23, 0x00, 0x6c, 0x6c, 0x04, 0x4f, 0x56, /// 0x62, 0x40, 0x0e, 0x9d, 0x1b, 0xd6]; /// let index = [0x48u8, 0x71, 0x65, 0x64]; /// let mut key_a = [0u8; 20]; /// srtcp_kdf_label(&key, &salt, -1, &index, SRTCP_LABEL_MSG_AUTH, &mut key_a).expect("Error with srtcp_kdf_label()"); /// } /// ``` #[cfg(kdf_srtp)] pub fn srtcp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8; SRTCP_INDEX_LEN], label: u8, keyout: &mut [u8]) -> Result<(), i32> { let key_size = crate::buffer_len_to_u32(key.len())?; let salt_size = crate::buffer_len_to_u32(salt.len())?; let keyout_size = crate::buffer_len_to_u32(keyout.len())?; let rc = unsafe { sys::wc_SRTCP_KDF_label(key.as_ptr(), key_size, salt.as_ptr(), salt_size, kdr_index, idx.as_ptr(), label, keyout.as_mut_ptr(), keyout_size) }; if rc != 0 { return Err(rc); } Ok(()) } /// Convert a Key Derivation Rate (KDR) value to an index for use in the /// SRTP/SRTCP KDF API. /// /// # Parameters /// /// * `kdr`: Key derivation rate to convert. /// /// # Returns /// /// Key derivation rate index (kdr_index). /// /// # Example /// /// ```rust /// #[cfg(kdf_srtp)] /// { /// use wolfssl_wolfcrypt::kdf::*; /// let kdr_index = srtp_kdr_to_index(16); /// } /// ``` #[cfg(kdf_srtp)] pub fn srtp_kdr_to_index(kdr: u32) -> i32 { unsafe { sys::wc_SRTP_KDF_kdr_to_idx(kdr) } }