streaming_crypto/core_api/crypto/
kdf.rs1use crate::constants::prf_ids;
24use crate::headers::types::HeaderV1;
25use crate::crypto::types::{KEY_LEN_32, CryptoError};
26
27use hkdf::Hkdf;
28use sha2::{Sha256, Sha512};
29use sha3::{Sha3_256, Sha3_512};
30use blake3::derive_key;
31
32#[inline]
37fn build_info_from_header(header: &HeaderV1) -> Vec<u8> {
38 let mut info = Vec::with_capacity(64);
39 info.extend_from_slice(&header.magic);
40 info.extend_from_slice(&header.version.to_le_bytes());
41 info.extend_from_slice(&header.alg_profile.to_le_bytes());
42 info.extend_from_slice(&header.cipher.to_le_bytes());
43 info.extend_from_slice(&header.hkdf_prf.to_le_bytes());
44 info.extend_from_slice(&header.compression.to_le_bytes());
45 info.extend_from_slice(&header.strategy.to_le_bytes());
46 info.extend_from_slice(&header.aad_domain.to_le_bytes());
47 info.extend_from_slice(&header.flags.to_le_bytes());
48 info.extend_from_slice(&header.chunk_size.to_le_bytes());
49 info.extend_from_slice(&header.key_id.to_le_bytes());
50 info
51}
52
53#[inline]
65pub fn derive_session_key_32(
66 master_key: &[u8],
67 header: &HeaderV1,
68) -> Result<[u8; KEY_LEN_32], CryptoError> {
69 if header.salt.iter().all(|&b| b == 0) {
70 return Err(CryptoError::Failure("salt must not be all-zero".into()));
71 }
72
73 let info = build_info_from_header(header);
74
75 match header.hkdf_prf {
76 x if x == prf_ids::SHA256 => {
77 let hk = Hkdf::<Sha256>::new(Some(&header.salt), master_key);
78 let mut key = [0u8; KEY_LEN_32];
79 hk.expand(&info, &mut key)
80 .map_err(|_| CryptoError::Failure("HKDF expand failed (SHA-256)".into()))?;
81 Ok(key)
82 }
83
84 x if x == prf_ids::SHA512 => {
85 let hk = Hkdf::<Sha512>::new(Some(&header.salt), master_key);
86 let mut key = [0u8; KEY_LEN_32];
87 hk.expand(&info, &mut key)
88 .map_err(|_| CryptoError::Failure("HKDF expand failed (SHA-512)".into()))?;
89 Ok(key)
90 }
91
92 x if x == prf_ids::SHA3_256 => {
93 let hk = Hkdf::<Sha3_256>::new(Some(&header.salt), master_key);
94 let mut key = [0u8; KEY_LEN_32];
95 hk.expand(&info, &mut key)
96 .map_err(|_| CryptoError::Failure("HKDF expand failed (SHA3-256)".into()))?;
97 Ok(key)
98 }
99
100 x if x == prf_ids::SHA3_512 => {
101 let hk = Hkdf::<Sha3_512>::new(Some(&header.salt), master_key);
102 let mut key = [0u8; KEY_LEN_32];
103 hk.expand(&info, &mut key)
104 .map_err(|_| CryptoError::Failure("HKDF expand failed (SHA3-512)".into()))?;
105 Ok(key)
106 }
107
108 x if x == prf_ids::BLAKE3K => {
109 let material = [master_key, &header.salt, &info].concat();
110 let key = derive_key("RSE1|HKDF|SESSION", &material);
111 Ok(key)
112 }
113
114 other => Err(CryptoError::UnsupportedPrf { prf_id: other }),
115 }
116}
117