1
/*
2
Licensed to the Apache Software Foundation (ASF) under one
3
or more contributor license agreements.  See the NOTICE file
4
distributed with this work for additional information
5
regarding copyright ownership.  The ASF licenses this file
6
to you under the Apache License, Version 2.0 (the
7
"License"); you may not use this file except in compliance
8
with the License.  You may obtain a copy of the License at
9

            
10
  http://www.apache.org/licenses/LICENSE-2.0
11

            
12
Unless required by applicable law or agreed to in writing,
13
software distributed under the License is distributed on an
14
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
KIND, either express or implied.  See the License for the
16
specific language governing permissions and limitations
17
under the License.
18
*/
19
use crate::std::{vec, Vec};
20

            
21
const HASH256_H0: u32 = 0x6A09_E667;
22
const HASH256_H1: u32 = 0xBB67_AE85;
23
const HASH256_H2: u32 = 0x3C6E_F372;
24
const HASH256_H3: u32 = 0xA54F_F53A;
25
const HASH256_H4: u32 = 0x510E_527F;
26
const HASH256_H5: u32 = 0x9B05_688C;
27
const HASH256_H6: u32 = 0x1F83_D9AB;
28
const HASH256_H7: u32 = 0x5BE0_CD19;
29

            
30
const HASH256_K: [u32; 64] = [
31
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
32
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
33
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
34
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
35
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
36
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
37
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
38
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
39
];
40

            
41
/// The block size of each round.
42
pub const BLOCK_SIZE: usize = 64;
43
/// Hash Length in Bytes
44
pub const HASH_BYTES: usize = 32;
45
// Ipad Byte
46
const IPAD_BYTE: u8 = 0x36;
47
// Opad Byte
48
const OPAD_BYTE: u8 = 0x5c;
49

            
50
pub struct HASH256 {
51
    length: [u32; 2],
52
    h: [u32; 8],
53
    w: [u32; 64],
54
}
55

            
56
impl HASH256 {
57
    fn s(n: u32, x: u32) -> u32 {
58
        return ((x) >> n) | ((x) << (32 - n));
59
    }
60
    fn r(n: u32, x: u32) -> u32 {
61
        return (x) >> n;
62
    }
63

            
64
    fn ch(x: u32, y: u32, z: u32) -> u32 {
65
        return (x & y) ^ (!(x) & z);
66
    }
67

            
68
    fn maj(x: u32, y: u32, z: u32) -> u32 {
69
        return (x & y) ^ (x & z) ^ (y & z);
70
    }
71
    fn sig0(x: u32) -> u32 {
72
        return HASH256::s(2, x) ^ HASH256::s(13, x) ^ HASH256::s(22, x);
73
    }
74

            
75
    fn sig1(x: u32) -> u32 {
76
        return HASH256::s(6, x) ^ HASH256::s(11, x) ^ HASH256::s(25, x);
77
    }
78

            
79
    fn theta0(x: u32) -> u32 {
80
        return HASH256::s(7, x) ^ HASH256::s(18, x) ^ HASH256::r(3, x);
81
    }
82

            
83
    fn theta1(x: u32) -> u32 {
84
        return HASH256::s(17, x) ^ HASH256::s(19, x) ^ HASH256::r(10, x);
85
    }
86

            
87
    fn transform(&mut self) {
88
        // basic transformation step
89
        for j in 16..64 {
90
            self.w[j] = HASH256::theta1(self.w[j - 2])
91
                .wrapping_add(self.w[j - 7])
92
                .wrapping_add(HASH256::theta0(self.w[j - 15]))
93
                .wrapping_add(self.w[j - 16]);
94
        }
95
        let mut a = self.h[0];
96
        let mut b = self.h[1];
97
        let mut c = self.h[2];
98
        let mut d = self.h[3];
99
        let mut e = self.h[4];
100
        let mut f = self.h[5];
101
        let mut g = self.h[6];
102
        let mut hh = self.h[7];
103
        for j in 0..64 {
104
            // 64 times - mush it up
105
            let t1 = hh
106
                .wrapping_add(HASH256::sig1(e))
107
                .wrapping_add(HASH256::ch(e, f, g))
108
                .wrapping_add(HASH256_K[j])
109
                .wrapping_add(self.w[j]);
110
            let t2 = HASH256::sig0(a).wrapping_add(HASH256::maj(a, b, c));
111
            hh = g;
112
            g = f;
113
            f = e;
114
            e = d.wrapping_add(t1);
115
            d = c;
116
            c = b;
117
            b = a;
118
            a = t1.wrapping_add(t2);
119
        }
120
        self.h[0] = self.h[0].wrapping_add(a);
121
        self.h[1] = self.h[1].wrapping_add(b);
122
        self.h[2] = self.h[2].wrapping_add(c);
123
        self.h[3] = self.h[3].wrapping_add(d);
124
        self.h[4] = self.h[4].wrapping_add(e);
125
        self.h[5] = self.h[5].wrapping_add(f);
126
        self.h[6] = self.h[6].wrapping_add(g);
127
        self.h[7] = self.h[7].wrapping_add(hh);
128
    }
129

            
130
    /// Initialise Hash function
131
    pub fn init(&mut self) {
132
        // initialise
133
        for i in 0..64 {
134
            self.w[i] = 0
135
        }
136
        self.length[0] = 0;
137
        self.length[1] = 0;
138
        self.h[0] = HASH256_H0;
139
        self.h[1] = HASH256_H1;
140
        self.h[2] = HASH256_H2;
141
        self.h[3] = HASH256_H3;
142
        self.h[4] = HASH256_H4;
143
        self.h[5] = HASH256_H5;
144
        self.h[6] = HASH256_H6;
145
        self.h[7] = HASH256_H7;
146
    }
147

            
148
    pub fn new() -> HASH256 {
149
        let mut nh = HASH256 {
150
            length: [0; 2],
151
            h: [0; 8],
152
            w: [0; 64],
153
        };
154
        nh.init();
155
        return nh;
156
    }
157

            
158
    /// Process a single byte
159
    pub fn process(&mut self, byt: u8) {
160
        /* process the next message byte */
161
        let cnt = ((self.length[0] / 32) % 16) as usize;
162
        self.w[cnt] <<= 8;
163
        self.w[cnt] |= (byt & 0xFF) as u32;
164
        self.length[0] += 8;
165
        if self.length[0] == 0 {
166
            self.length[1] += 1;
167
            self.length[0] = 0
168
        }
169
        if (self.length[0] % 512) == 0 {
170
            self.transform()
171
        }
172
    }
173

            
174
    /// Process an array of bytes
175
    pub fn process_array(&mut self, b: &[u8]) {
176
        for i in 0..b.len() {
177
            self.process(b[i])
178
        }
179
    }
180

            
181
    /// Process a 32-bit integer
182
    pub fn process_num(&mut self, n: i32) {
183
        self.process(((n >> 24) & 0xff) as u8);
184
        self.process(((n >> 16) & 0xff) as u8);
185
        self.process(((n >> 8) & 0xff) as u8);
186
        self.process((n & 0xff) as u8);
187
    }
188

            
189
    /// Generate 32-byte Hash
190
    pub fn hash(&mut self) -> [u8; HASH_BYTES] {
191
        // pad message and finish - supply digest
192
        let mut digest: [u8; 32] = [0; 32];
193
        let len0 = self.length[0];
194
        let len1 = self.length[1];
195
        self.process(0x80);
196
        while (self.length[0] % 512) != 448 {
197
            self.process(0)
198
        }
199
        self.w[14] = len1;
200
        self.w[15] = len0;
201
        self.transform();
202
        for i in 0..32 {
203
            // convert to bytes
204
            digest[i] = ((self.h[i / 4] >> (8 * (3 - i % 4))) & 0xff) as u8;
205
        }
206
        self.init();
207
        return digest;
208
    }
209

            
210
    /// Generate a HMAC
211
    ///
212
    /// https://tools.ietf.org/html/rfc2104
213
    pub fn hmac(key: &[u8], text: &[u8]) -> [u8; HASH_BYTES] {
214
        let mut k = key.to_vec();
215

            
216
        // Verify length of key < BLOCK_SIZE
217
        if k.len() > BLOCK_SIZE {
218
            // Reduce key to 32 bytes by hashing
219
            let mut hash256 = HASH256::new();
220
            hash256.init();
221
            hash256.process_array(&k);
222
            k = hash256.hash().to_vec();
223
        }
224

            
225
        // Prepare inner and outer paddings
226
        // inner = (ipad XOR k)
227
        // outer = (opad XOR k)
228
        let mut inner = vec![IPAD_BYTE; BLOCK_SIZE];
229
        let mut outer = vec![OPAD_BYTE; BLOCK_SIZE];
230
        for (i, byte) in k.iter().enumerate() {
231
            inner[i] = inner[i] ^ byte;
232
            outer[i] = outer[i] ^ byte;
233
        }
234

            
235
        // Concatenate inner with text = (ipad XOR k || text)
236
        inner.extend_from_slice(text);
237

            
238
        // hash inner = H(ipad XOR k || text)
239
        let mut hash256 = HASH256::new();
240
        hash256.init();
241
        hash256.process_array(&inner);
242
        let inner = hash256.hash();
243

            
244
        // Concatenate outer with hash of inner = (opad XOR k) || H(ipad XOR k || text)
245
        outer.extend_from_slice(&inner);
246

            
247
        // Final hash = H((opad XOR k) || H(ipad XOR k || text))
248
        let mut hash256 = HASH256::new();
249
        hash256.init();
250
        hash256.process_array(&outer);
251
        hash256.hash()
252
    }
253

            
254
    /// HKDF-Extract
255
    ///
256
    /// https://tools.ietf.org/html/rfc5869
257
    pub fn hkdf_extract(salt: &[u8], ikm: &[u8]) -> [u8; HASH_BYTES] {
258
        HASH256::hmac(salt, ikm)
259
    }
260

            
261
    /// HKDF-Extend
262
    ///
263
    /// https://tools.ietf.org/html/rfc5869
264
    pub fn hkdf_extend(prk: &[u8], info: &[u8], l: u8) -> Vec<u8> {
265
        // n = cieling(l / 32)
266
        let mut n = l / (HASH_BYTES as u8);
267
        if n * (HASH_BYTES as u8) < l {
268
            n += 1;
269
        }
270

            
271
        let mut okm: Vec<u8> = vec![];
272
        let mut previous = vec![]; // T(0) = []
273

            
274
        for i in 0..n as usize {
275
            // Concatenate (T(i) || info || i)
276
            let mut text: Vec<u8> = previous;
277
            text.extend_from_slice(info);
278
            text.push((i + 1) as u8); // Note: i <= 254
279

            
280
            // T(i+1) = HMAC(PRK, T(i) || info || i)
281
            previous = HASH256::hmac(prk, &text).to_vec();
282
            okm.extend_from_slice(&previous);
283
        }
284

            
285
        // Reduce length to size L
286
        okm.resize(l as usize, 0);
287
        okm
288
    }
289
}
290

            
291
#[cfg(test)]
292
mod tests {
293
    use super::*;
294

            
295
    #[test]
296
    fn test_hmac_simple() {
297
        let text = [0x0a];
298
        let key = [0x0b];
299
        let expected =
300
            hex::decode("b1746117c186405d121d52866f48270fdeb2177d67f6922f0a031e0101658624")
301
                .unwrap();
302

            
303
        let output = HASH256::hmac(&key, &text);
304
        assert_eq!(expected, output);
305
    }
306

            
307
    #[test]
308
    fn test_hmac_empty() {
309
        let text = [];
310
        let key = [];
311
        let expected =
312
            hex::decode("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad")
313
                .unwrap();
314

            
315
        let output = HASH256::hmac(&key, &text);
316
        assert_eq!(expected, output);
317
    }
318

            
319
    #[test]
320
    fn test_hmac_32_byte_key() {
321
        let text = [0x0a];
322
        let key = hex::decode("abababababababababababababababababababababababababababababababab")
323
            .unwrap();
324
        let expected =
325
            hex::decode("43997a72e7b3b1c19e5566c940d5f2961c96802b58a3da2acd19dcc1a90a8d05")
326
                .unwrap();
327

            
328
        let output = HASH256::hmac(&key, &text);
329
        assert_eq!(expected, output);
330
    }
331

            
332
    #[test]
333
    fn test_hmac_64_byte_key() {
334
        let text = [0x0a];
335
        let key = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
336
        let expected =
337
            hex::decode("93a88773df742079e3512f3d10f4f8ac674e24c4eda78df46c2376dd3946750b")
338
                .unwrap();
339

            
340
        let output = HASH256::hmac(&key, &text);
341
        assert_eq!(expected, output);
342
    }
343

            
344
    #[test]
345
    fn test_hmac_65_byte_key() {
346
        let text = [0x0a];
347
        let key = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0B").unwrap();
348
        let expected =
349
            hex::decode("7c8dd5068bcff3347dd13a7493247444635b51cf000b18f37a74a55cec3413fb")
350
                .unwrap();
351

            
352
        let output = HASH256::hmac(&key, &text);
353
        assert_eq!(expected, output);
354
    }
355

            
356
    #[test]
357
    fn test_hmac_65_byte_text() {
358
        let text = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0B").unwrap();
359
        let key = [0x0b];
360
        let expected =
361
            hex::decode("f04344808f2fcdafe1c20272a29b1ce4be00c916a2c14700b82b81c6eae9dd96")
362
                .unwrap();
363

            
364
        let output = HASH256::hmac(&key, &text);
365
        assert_eq!(expected, output);
366
    }
367

            
368
    #[test]
369
    fn test_hkdf_case_1() {
370
        // From https://tools.ietf.org/html/rfc5869
371
        let ikm = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
372
        let salt = hex::decode("000102030405060708090a0b0c").unwrap();
373
        let expected_prk =
374
            hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
375
                .unwrap();
376

            
377
        let output_prk = HASH256::hkdf_extract(&salt, &ikm).to_vec();
378
        assert_eq!(expected_prk, output_prk);
379

            
380
        let info = hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap();
381
        let l = 42;
382
        let expected_okm = hex::decode(
383
            "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
384
        )
385
        .unwrap();
386

            
387
        let output_okm = HASH256::hkdf_extend(&expected_prk, &info, l);
388
        assert_eq!(expected_okm, output_okm);
389
    }
390

            
391
    #[test]
392
    fn test_hkdf_case_2() {
393
        // From https://tools.ietf.org/html/rfc5869
394
        let ikm = hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f")
395
            .unwrap();
396
        let salt = hex::decode("606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf")
397
            .unwrap();
398
        let expected_prk =
399
            hex::decode("06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244")
400
                .unwrap();
401

            
402
        let output_prk = HASH256::hkdf_extract(&salt, &ikm).to_vec();
403
        assert_eq!(expected_prk, output_prk);
404

            
405
        let info = hex::decode("b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
406
            .unwrap();
407
        let l = 82;
408
        let expected_okm = hex::decode("b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87")
409
            .unwrap();
410

            
411
        let output_okm = HASH256::hkdf_extend(&expected_prk, &info, l);
412
        assert_eq!(expected_okm, output_okm);
413
    }
414

            
415
    #[test]
416
    fn test_hkdf_case_3() {
417
        // From https://tools.ietf.org/html/rfc5869
418
        let ikm = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
419
        let salt = vec![];
420
        let expected_prk =
421
            hex::decode("19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04")
422
                .unwrap();
423

            
424
        let output_prk = HASH256::hkdf_extract(&salt, &ikm).to_vec();
425
        assert_eq!(expected_prk, output_prk);
426

            
427
        let info = vec![];
428
        let l = 42;
429
        let expected_okm = hex::decode(
430
            "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8",
431
        )
432
        .unwrap();
433

            
434
        let output_okm = HASH256::hkdf_extend(&expected_prk, &info, l);
435
        assert_eq!(expected_okm, output_okm);
436
    }
437
}