mysql_connector/utils/
scramble.rs1use sha1::{Digest, Sha1};
2
3fn xor<T, U>(mut left: T, right: U) -> T
4where
5 T: AsMut<[u8]>,
6 U: AsRef<[u8]>,
7{
8 for (l, r) in left.as_mut().iter_mut().zip(right.as_ref().iter()) {
9 *l ^= r;
10 }
11 left
12}
13
14pub fn scramble_native(nonce: &[u8], password: &[u8]) -> Option<[u8; 20]> {
16 if password.is_empty() {
17 return None;
18 }
19
20 fn sha1<T: AsRef<[u8]>>(bytes: &[T]) -> [u8; 20] {
21 let mut hasher = Sha1::new();
22 for bytes in bytes {
23 hasher.update(bytes);
24 }
25 hasher.finalize().into()
26 }
27
28 Some(xor(
29 sha1(&[password]),
30 sha1(&[nonce, &sha1(&[sha1(&[password])])]),
31 ))
32}
33
34#[cfg(feature = "caching-sha2-password")]
36#[cfg_attr(doc, doc(cfg(feature = "caching-sha2-password")))]
37pub fn scramble_sha256(nonce: &[u8], password: &[u8]) -> Option<[u8; 32]> {
38 if password.is_empty() {
39 return None;
40 }
41
42 fn sha256<T: AsRef<[u8]>>(bytes: &[T]) -> [u8; 32] {
43 let mut hasher = sha2::Sha256::new();
44 for bytes in bytes {
45 hasher.update(bytes);
46 }
47 hasher.finalize().into()
48 }
49
50 Some(xor(
51 sha256(&[password]),
52 sha256(&[&sha256(&[sha256(&[password])])[..], nonce]),
53 ))
54}