1#[cfg(feature = "server")]
21pub mod password;
22pub mod kex;
23
24use why2::
25{
26 encrypter,
27 decrypter,
28 grid::Grid,
29 types::EncryptedData,
30 auth::AuthenticatedData,
31};
32
33use zeroize::Zeroizing;
34
35use hkdf::Hkdf;
36use sha2::{ Sha256, Digest };
37
38use crate::options;
39
40pub fn get_correct_key<const W: usize, const H: usize>(key: &Zeroizing<Vec<i64>>) -> Zeroizing<Vec<i64>> {
43 let mut key_bytes = Vec::with_capacity(key.len() * 8);
45 for val in key.iter()
46 {
47 key_bytes.extend_from_slice(&val.to_be_bytes());
48 }
49
50 let hkdf = Hkdf::<Sha256>::new(None, &key_bytes);
52
53 let required_len = W * H * 2;
54 let needed_bytes = required_len * 8;
55 let mut output_bytes = vec![0u8; needed_bytes];
56
57 hkdf.expand(format!("WHY2-DERIVED-KEY-{W}x{H}").as_bytes(), &mut output_bytes).expect("Key derivation failed");
59
60 let mut derived_key = Vec::with_capacity(required_len);
62 for chunk in output_bytes.chunks_exact(8)
63 {
64 let mut buf = [0u8; 8];
65 buf.copy_from_slice(chunk);
66 derived_key.push(i64::from_be_bytes(buf));
67 }
68
69 Zeroizing::new(derived_key)
70}
71
72pub fn sha256(seed_str: &str) -> [u8; 32] {
75 let mut hasher = Sha256::new();
77 hasher.update(seed_str.as_bytes());
78
79 hasher.finalize().into()
81}
82
83pub fn encrypt_packet<const W: usize, const H: usize>(packet_bytes: Vec<u8>, keys: &options::SharedKeys) -> Vec<u8>
84{
85 let mut input_i64 = Vec::with_capacity((packet_bytes.len() + 7) / 8);
87 for chunk in packet_bytes.chunks(8)
88 {
89 let mut buf = [0u8; 8];
90 buf[..chunk.len()].copy_from_slice(chunk);
91 input_i64.push(i64::from_be_bytes(buf));
92 }
93
94 let key = if keys.0.len() == W * H * 2
96 {
97 &keys.0
98 } else
99 {
100 &get_correct_key::<W, H>(&keys.0)
101 };
102
103 let encrypted_data = encrypter::encrypt::<W, H>(&input_i64, Some(key))
105 .expect("Encrypting packet failed");
106
107 AuthenticatedData::authenticate(encrypted_data, keys.1.as_slice().try_into().unwrap()).into()
109}
110
111pub fn decrypt_packet<const W: usize, const H: usize>(mut decoded_packet: Vec<u8>, keys: &options::SharedKeys) -> Option<Vec<u8>>
112{
113 let auth_packet: AuthenticatedData<W, H> = decoded_packet.as_slice().try_into().ok()?;
115
116 if !auth_packet.verify(keys.1.as_slice().try_into().ok()?)
118 {
119 return None;
120 }
121
122 let key = if keys.0.len() == W * H * 2
124 {
125 &keys.0
126 } else
127 {
128 &get_correct_key::<W, H>(&keys.0)
129 };
130
131 let decrypted_packet = decrypter::decrypt(EncryptedData
133 {
134 output: auth_packet.encrypted_data.output,
135 key: Grid::from_key(&key).ok()?,
136 nonce: auth_packet.encrypted_data.nonce,
137 }).ok()?;
138
139 decoded_packet = Vec::with_capacity(decrypted_packet.output.len() * 8);
141 for val in decrypted_packet.output.to_vec()
142 {
143 decoded_packet.extend_from_slice(&val.to_be_bytes());
144 }
145
146 Some(decoded_packet)
147}