1use md5::{Digest, Md5};
2use ring::aead::{Nonce, NONCE_LEN};
3use ring::hkdf::{KeyType, Salt, HKDF_SHA1_FOR_LEGACY_USE_ONLY};
4
5pub struct NonceSequence {
8 nonce: [u8; NONCE_LEN],
9 is_first: bool,
10}
11
12impl NonceSequence {
13 pub fn new() -> Self {
14 NonceSequence {
15 nonce: [0u8; NONCE_LEN],
16 is_first: true,
17 }
18 }
19
20 pub fn increment(&mut self) -> &[u8] {
22 if self.is_first {
23 self.is_first = false;
24 return &self.nonce;
25 }
26
27 for i in 0..self.nonce.len() {
28 if self.nonce[i] < 0xff {
29 self.nonce[i] += 1;
30 break;
31 } else {
32 self.nonce[i] = 0;
33 }
34 }
35 return &self.nonce;
36 }
37}
38
39impl ring::aead::NonceSequence for NonceSequence {
41 fn advance(&mut self) -> Result<ring::aead::Nonce, ring::error::Unspecified> {
42 Nonce::try_assume_unique_for_key(self.increment())
43 }
44}
45
46pub struct NonceZeroSequence {}
48const NONCE_ALL_ZERO: [u8; NONCE_LEN] = [0u8; NONCE_LEN];
49impl ring::aead::NonceSequence for NonceZeroSequence {
51 fn advance(&mut self) -> Result<ring::aead::Nonce, ring::error::Unspecified> {
52 Nonce::try_assume_unique_for_key(&NONCE_ALL_ZERO)
53 }
54}
55
56pub fn hkdf_sha1(key: &[u8], salt: &[u8]) -> Vec<u8> {
57 const SUBKEY_INFO: &'static [u8] = b"ss-subkey";
58 let mut sub_key = Vec::<u8>::from([0u8; 64]);
59
60 struct CryptoKeyType(usize);
61 impl KeyType for CryptoKeyType {
62 fn len(&self) -> usize {
63 self.0
64 }
65 }
66
67 let s = Salt::new(HKDF_SHA1_FOR_LEGACY_USE_ONLY, salt);
68 let prk = s.extract(key);
69 let okm = prk
70 .expand(&[SUBKEY_INFO], CryptoKeyType(key.len()))
71 .expect("hkdf_sha1_expand");
72 sub_key.truncate(key.len());
73 okm.fill(&mut sub_key).expect("hkdf_sha1_fill");
74
75 sub_key
76}
77
78pub fn evp_bytes_to_key(password: &[u8], key_len: usize) -> Box<[u8]> {
79 let mut key = vec![0u8; key_len];
80 let mut last = None;
81 let mut offset = 0usize;
82 while offset < key_len {
83 let mut m = Md5::new();
84
85 if let Some(digest) = last {
86 m.update(&digest);
87 }
88
89 m.update(password);
90
91 let digest = m.finalize();
92
93 let amt = std::cmp::min(key_len - offset, digest.len());
94 key[offset..offset + amt].copy_from_slice(&digest[..amt]);
95
96 offset += amt;
97 last = Some(digest);
98 }
99
100 key.into_boxed_slice()
101}
102
103#[cfg(test)]
104mod tests {
105
106 use super::{evp_bytes_to_key, hkdf_sha1, NonceSequence};
107 #[test]
108 fn test_nonce_increment() {
109 let mut seq = NonceSequence::new();
110 for i in 0..=255 {
111 assert_eq!(seq.increment(), [i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
112 }
113 for i in 0..=255 {
114 assert_eq!(seq.increment(), [i, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
115 }
116 }
117
118 #[test]
119 fn test_hkdf_sha1() {
120 let sub_key = hkdf_sha1(&[0u8; 16], &[0u8; 32]);
121 println!("{:?}", sub_key)
122 }
123
124 #[test]
125 fn test_evp_bytes_to_key() {
126 let key = evp_bytes_to_key(b"foobar", 32);
127 assert_eq!(
128 &key[..],
129 &[
130 0x38u8, 0x58, 0xf6, 0x22, 0x30, 0xac, 0x3c, 0x91, 0x5f, 0x30, 0x0c, 0x66, 0x43,
131 0x12, 0xc6, 0x3f, 0x56, 0x83, 0x78, 0x52, 0x96, 0x14, 0xd2, 0x2d, 0xdb, 0x49, 0x23,
132 0x7d, 0x2f, 0x60, 0xbf, 0xdf
133 ]
134 )
135 }
136}