Merge pull request #9357 from holtrop/rust-wc-srtp-kdf
Rust wrapper: add SRTP/SRTCP KDF functions to kdf module
This commit is contained in:
@@ -195,7 +195,7 @@ int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
|
||||
\sa wc_SRTP_KDF_label
|
||||
\sa wc_SRTP_KDF_kdr_to_idx
|
||||
*/
|
||||
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
|
||||
int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt,
|
||||
word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
|
||||
word32 outKeySz);
|
||||
/*!
|
||||
|
||||
@@ -29,6 +29,15 @@ the raw C functions in a memory-safe and easy-to-use Rust API.
|
||||
use crate::wolfcrypt::hmac::HMAC;
|
||||
use wolfssl_sys as ws;
|
||||
|
||||
pub const SRTP_LABEL_ENCRYPTION: u8 = ws::WC_SRTP_LABEL_ENCRYPTION as u8;
|
||||
pub const SRTP_LABEL_MSG_AUTH: u8 = ws::WC_SRTP_LABEL_MSG_AUTH as u8;
|
||||
pub const SRTP_LABEL_SALT: u8 = ws::WC_SRTP_LABEL_SALT as u8;
|
||||
pub const SRTCP_LABEL_ENCRYPTION: u8 = ws::WC_SRTCP_LABEL_ENCRYPTION as u8;
|
||||
pub const SRTCP_LABEL_MSG_AUTH: u8 = ws::WC_SRTCP_LABEL_MSG_AUTH as u8;
|
||||
pub const SRTCP_LABEL_SALT: u8 = ws::WC_SRTCP_LABEL_SALT as u8;
|
||||
pub const SRTP_LABEL_HDR_ENCRYPTION: u8 = ws::WC_SRTP_LABEL_HDR_ENCRYPTION as u8;
|
||||
pub const SRTP_LABEL_HDR_SALT: u8 = ws::WC_SRTP_LABEL_HDR_SALT as u8;
|
||||
|
||||
/// Perform RFC 5869 HKDF-Extract operation for TLS v1.3 key derivation.
|
||||
///
|
||||
/// # Parameters
|
||||
@@ -189,3 +198,208 @@ pub fn ssh_kdf(typ: i32, key_id: u8, k: &[u8], h: &[u8], session_id: &[u8], key:
|
||||
}
|
||||
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
|
||||
/// 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()");
|
||||
/// ```
|
||||
pub fn srtp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8],
|
||||
key1: &mut [u8], key2: &mut [u8], key3: &mut [u8]) -> Result<(), i32> {
|
||||
let key_size = key.len() as u32;
|
||||
let salt_size = salt.len() as u32;
|
||||
let key1_size = key1.len() as u32;
|
||||
let key2_size = key2.len() as u32;
|
||||
let key3_size = key3.len() as u32;
|
||||
let rc = unsafe {
|
||||
ws::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
|
||||
/// 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()");
|
||||
/// ```
|
||||
pub fn srtp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8],
|
||||
label: u8, keyout: &mut [u8]) -> Result<(), i32> {
|
||||
let key_size = key.len() as u32;
|
||||
let salt_size = salt.len() as u32;
|
||||
let keyout_size = keyout.len() as u32;
|
||||
let rc = unsafe {
|
||||
ws::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
|
||||
/// 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];
|
||||
/// srtcp_kdf(&key, &salt, -1, &index, &mut key_e, &mut key_a, &mut key_s).expect("Error with srtcp_kdf()");
|
||||
/// ```
|
||||
pub fn srtcp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8],
|
||||
key1: &mut [u8], key2: &mut [u8], key3: &mut [u8]) -> Result<(), i32> {
|
||||
let key_size = key.len() as u32;
|
||||
let salt_size = salt.len() as u32;
|
||||
let key1_size = key1.len() as u32;
|
||||
let key2_size = key2.len() as u32;
|
||||
let key3_size = key3.len() as u32;
|
||||
let rc = unsafe {
|
||||
ws::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
|
||||
/// 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];
|
||||
/// srtcp_kdf_label(&key, &salt, -1, &index, SRTCP_LABEL_MSG_AUTH, &mut key_a).expect("Error with srtcp_kdf_label()");
|
||||
/// ```
|
||||
pub fn srtcp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8],
|
||||
label: u8, keyout: &mut [u8]) -> Result<(), i32> {
|
||||
let key_size = key.len() as u32;
|
||||
let salt_size = salt.len() as u32;
|
||||
let keyout_size = keyout.len() as u32;
|
||||
let rc = unsafe {
|
||||
ws::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
|
||||
/// use wolfssl::wolfcrypt::kdf::*;
|
||||
/// let kdr_index = srtp_kdr_to_index(16);
|
||||
/// ```
|
||||
pub fn srtp_kdr_to_index(kdr: u32) -> i32 {
|
||||
unsafe { ws::wc_SRTP_KDF_kdr_to_idx(kdr) }
|
||||
}
|
||||
|
||||
@@ -91,3 +91,109 @@ fn test_ssh_kdf() {
|
||||
|
||||
assert_eq!(out, ssh_kdf_set3_a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_srtp_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 expected_ke = [
|
||||
0xdcu8, 0x38, 0x21, 0x92, 0xab, 0x65, 0x10, 0x8a,
|
||||
0x86, 0xb2, 0x59, 0xb6, 0x1b, 0x3a, 0xf4, 0x6f
|
||||
];
|
||||
let expected_ka = [
|
||||
0xb8u8, 0x39, 0x37, 0xfb, 0x32, 0x17, 0x92, 0xee,
|
||||
0x87, 0xb7, 0x88, 0x19, 0x3b, 0xe5, 0xa4, 0xe3,
|
||||
0xbd, 0x32, 0x6e, 0xe4
|
||||
];
|
||||
let expected_ks = [
|
||||
0xf1u8, 0xc0, 0x35, 0xc0, 0x0b, 0x5a, 0x54, 0xa6,
|
||||
0x16, 0x92, 0xc0, 0x16, 0x27, 0x6c
|
||||
];
|
||||
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()");
|
||||
assert_eq!(key_e, expected_ke);
|
||||
assert_eq!(key_a, expected_ka);
|
||||
assert_eq!(key_s, expected_ks);
|
||||
|
||||
let mut key_e = [0u8; 16];
|
||||
srtp_kdf_label(&key, &salt, -1, &index, SRTP_LABEL_ENCRYPTION, &mut key_e).expect("Error with srtp_kdf_label()");
|
||||
assert_eq!(key_e, expected_ke);
|
||||
|
||||
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()");
|
||||
assert_eq!(key_a, expected_ka);
|
||||
|
||||
let mut key_s = [0u8; 14];
|
||||
srtp_kdf_label(&key, &salt, -1, &index, SRTP_LABEL_SALT, &mut key_s).expect("Error with srtp_kdf_label()");
|
||||
assert_eq!(key_s, expected_ks);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_srtcp_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 = [
|
||||
0x56u8, 0xf3, 0xf1, 0x97
|
||||
];
|
||||
let expected_ke = [
|
||||
0xabu8, 0x5b, 0xe0, 0xb4, 0x56, 0x23, 0x5d, 0xcf,
|
||||
0x77, 0xd5, 0x08, 0x69, 0x29, 0xba, 0xfb, 0x38
|
||||
];
|
||||
let expected_ka = [
|
||||
0xc5u8, 0x2f, 0xde, 0x0b, 0x80, 0xb0, 0xf0, 0xba,
|
||||
0xd8, 0xd1, 0x56, 0x45, 0xcb, 0x86, 0xe7, 0xc7,
|
||||
0xc3, 0xd8, 0x77, 0x0e
|
||||
];
|
||||
let expected_ks = [
|
||||
0xdeu8, 0xb5, 0xf8, 0x5f, 0x81, 0x33, 0x6a, 0x96,
|
||||
0x5e, 0xd3, 0x2b, 0xb7, 0xed, 0xe8
|
||||
];
|
||||
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()");
|
||||
assert_eq!(key_e, expected_ke);
|
||||
assert_eq!(key_a, expected_ka);
|
||||
assert_eq!(key_s, expected_ks);
|
||||
|
||||
let mut key_e = [0u8; 16];
|
||||
srtcp_kdf_label(&key, &salt, -1, &index, SRTCP_LABEL_ENCRYPTION, &mut key_e).expect("Error with srtcp_kdf_label()");
|
||||
assert_eq!(key_e, expected_ke);
|
||||
|
||||
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()");
|
||||
assert_eq!(key_a, expected_ka);
|
||||
|
||||
let mut key_s = [0u8; 14];
|
||||
srtcp_kdf_label(&key, &salt, -1, &index, SRTCP_LABEL_SALT, &mut key_s).expect("Error with srtcp_kdf_label()");
|
||||
assert_eq!(key_s, expected_ks);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_srtp_kdr_to_idx() {
|
||||
assert_eq!(srtp_kdr_to_index(0), -1);
|
||||
assert_eq!(srtp_kdr_to_index(1), 0);
|
||||
assert_eq!(srtp_kdr_to_index(2), 1);
|
||||
assert_eq!(srtp_kdr_to_index(4), 2);
|
||||
assert_eq!(srtp_kdr_to_index(8), 3);
|
||||
assert_eq!(srtp_kdr_to_index(16), 4);
|
||||
assert_eq!(srtp_kdr_to_index(65536), 16);
|
||||
assert_eq!(srtp_kdr_to_index(1048576), 20);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user