1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
use libc::size_t;
use nettle_sys::{nettle_hmac_digest, nettle_hmac_set_key, nettle_hmac_update};
use std::mem::zeroed;
use std::os::raw::c_void;
use std::slice;

use crate::hash::NettleHash;
use crate::{hash::Hash, mac::Mac, Result};

/// Hashed message authentication code.
pub struct Hmac<H: Hash + NettleHash> {
    outer: H::Context,
    inner: H::Context,
    state: H::Context,
}

impl<H: NettleHash> Hmac<H> {
    /// Create a new MAC instance with secret `key`.
    pub fn with_key(key: &[u8]) -> Self {
        unsafe {
            let mut ret: Hmac<H> = zeroed();

            nettle_hmac_set_key(
                (&mut ret.outer as *mut H::Context) as *mut _,
                (&mut ret.inner as *mut H::Context) as *mut _,
                (&mut ret.state as *mut H::Context) as *mut _,
                H::nettle_hash() as *const _,
                key.len(),
                key.as_ptr(),
            );
            ret
        }
    }

    #[doc(hidden)]
    pub extern "C" fn nettle_update(
        ctx: *mut c_void,
        length: size_t,
        src: *const u8,
    ) {
        unsafe {
            let ctx: &mut Hmac<H> = &mut *(ctx as *mut Hmac<H>);
            let src = slice::from_raw_parts(src, length);

            ctx.update(src);
        }
    }

    #[doc(hidden)]
    pub extern "C" fn nettle_digest(
        ctx: *mut c_void,
        length: size_t,
        dst: *mut u8,
    ) {
        unsafe {
            let ctx: &mut Hmac<H> = &mut *(ctx as *mut Hmac<H>);
            let src = slice::from_raw_parts_mut(dst, length);

            ctx.digest(src).unwrap();
        }
    }
}

impl<H: NettleHash> Mac for Hmac<H> {
    fn mac_size(&self) -> usize {
        H::default().digest_size()
    }

    fn update(&mut self, data: &[u8]) {
        unsafe {
            nettle_hmac_update(
                (&mut self.state as *mut H::Context) as *mut _,
                H::nettle_hash() as *const _,
                data.len(),
                data.as_ptr(),
            );
        }
    }

    fn digest(&mut self, digest: &mut [u8]) -> Result<()> {
        unsafe {
            nettle_hmac_digest(
                (&self.outer as *const H::Context) as *const _,
                (&self.inner as *const H::Context) as *const _,
                (&mut self.state as *mut H::Context) as *mut _,
                H::nettle_hash() as *const _,
                digest.len(),
                digest.as_mut_ptr(),
            );
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::hash::insecure_do_not_use::Sha1;
    use crate::hash::{Sha224, Sha256, Sha384, Sha512};

    #[test]
    fn cavp_sha1() {
        {
            let mut hmac = Hmac::<Sha1>::with_key(
                &b"\x82\xf3\xb6\x9a\x1b\xff\x4d\xe1\x5c\x33"[..],
            );
            let mut digest = vec![0u8; 20];

            hmac.update(&b"\xfc\xd6\xd9\x8b\xef\x45\xed\x68\x50\x80\x6e\x96\xf2\x55\xfa\x0c\x81\x14\xb7\x28\x73\xab\xe8\xf4\x3c\x10\xbe\xa7\xc1\xdf\x70\x6f\x10\x45\x8e\x6d\x4e\x1c\x92\x01\xf0\x57\xb8\x49\x2f\xa1\x0f\xe4\xb5\x41\xd0\xfc\x9d\x41\xef\x83\x9a\xcf\xf1\xbc\x76\xe3\xfd\xfe\xbf\x22\x35\xb5\xbd\x03\x47\xa9\xa6\x30\x3e\x83\x15\x2f\x9f\x8d\xb9\x41\xb1\xb9\x4a\x8a\x1c\xe5\xc2\x73\xb5\x5d\xc9\x4d\x99\xa1\x71\x37\x79\x69\x23\x41\x34\xe7\xda\xd1\xab\x4c\x8e\x46\xd1\x8d\xf4\xdc\x01\x67\x64\xcf\x95\xa1\x1a\xc4\xb4\x91\xa2\x64\x6b\xe1"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\x1b\xa0\xe6\x6c\xf7\x2e\xfc\x34\x92\x07"[..],
                &digest[..10]
            );
        }

        {
            let mut hmac = Hmac::<Sha1>::with_key(
                &b"\x47\x66\xe6\xfe\x5d\xff\xc9\x8a\x5c\x50"[..],
            );
            let mut digest = vec![0u8; 20];

            hmac.update(&b"\xd6\x8b\x82\x8a\x15\x3f\x51\x98\xc0\x05\xee\x36\xc0\xaf\x2f\xf9\x2e\x84\x90\x75\x17\xf0\x1d\x9b\x7c\x79\x93\x46\x9d\xf5\xc2\x10\x78\xfa\x35\x6a\x8c\x97\x15\xec\xe2\x41\x4b\xe9\x4e\x10\xe5\x47\xf3\x2c\xbb\x8d\x05\x82\x52\x3e\xd3\xbb\x00\x66\x04\x6e\x51\x72\x20\x94\xaa\x44\x53\x3d\x2c\x87\x6e\x82\xdb\x40\x2f\xbb\x00\xa6\xc2\xf2\xcc\x34\x87\x97\x3d\xfc\x16\x74\x46\x3e\x81\xe4\x2a\x39\xd9\x40\x29\x41\xf3\x9b\x5e\x12\x6b\xaf\xe8\x64\xea\x16\x48\xc0\xa5\xbe\x0a\x91\x26\x97\xa8\x7e\x4f\x8e\xab\xf7\x9c\xbf\x13\x0e"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\x00\x7e\x45\x04\x04\x1a\x12\xf9\xe3\x45"[..],
                &digest[..10]
            );
        }

        {
            let mut hmac = Hmac::<Sha1>::with_key(
                &b"\x0f\x94\x2d\x98\xa5\xc4\x06\x15\x59\x67"[..],
            );
            let mut digest = vec![0u8; 20];

            hmac.update(&b"\xf8\x4d\x0d\x81\x3d\x2e\x9e\x77\x9e\x85\x70\xbd\xdb\xdf\x6f\xdc\x6b\xaa\xde\x5a\xcb\x3c\x4c\xde\x16\x18\xc4\x94\xd6\x6d\x45\xd3\x19\xe0\x71\xfe\xc8\x8b\x89\xa8\x35\x46\x99\xfb\xf3\x25\xf0\x5a\xea\x42\xd3\x45\xaa\xbc\x73\x7d\x00\xff\x1c\x69\xc7\x46\xae\xb9\x01\x5f\x51\x49\x27\xae\x65\x48\xbd\x75\xb8\x99\x28\x53\xfc\x79\xc4\x0a\x78\x63\x32\x85\xfd\x30\xef\x19\x1c\x83\x2b\x0b\x96\x64\xd8\x52\x14\x2b\x01\x9f\x18\xa0\x5d\x9b\x34\x60\x24\x6f\x7a\x83\x21\x8a\x33\x7b\x09\x9e\xd4\x3f\x0b\xec\x2d\xaa\xa8\xc2\xe4\x1d"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\xc1\x9d\x05\xa8\x08\x05\x4b\x80\x39\xf9"[..],
                &digest[..10]
            );
        }

        {
            let mut hmac = Hmac::<Sha1>::with_key(
                &b"\x78\xcb\x19\x4a\x95\x8f\xc1\xb9\x5e\x35"[..],
            );
            let mut digest = vec![0u8; 20];

            hmac.update(&b"\xd6\xeb\x23\xc5\xea\x87\xfd\x67\xb9\x43\x92\x8b\xe0\x52\x18\x23\xdc\x50\x8a\xcb\x2a\xd5\xf0\xfd\xac\x49\xe0\x84\x4f\xfa\x45\x33\xeb\x6b\x5f\xd6\x6b\xf0\x0b\x69\x2d\x77\x45\x88\xac\xa9\xeb\x27\x5c\x32\xc3\x83\xd5\x5c\xc0\x58\x34\xe3\x81\x55\xbe\x05\x1b\xcd\xc7\xd8\x18\xaf\xd3\xe0\xc0\xb8\xfa\xe1\x97\xe7\x91\xf2\x26\x32\x06\xd3\xfe\x77\x0c\x80\xfb\xb5\xf8\x06\xc6\x7c\x6b\x96\x9d\xa2\x32\xd8\x57\x38\x6a\x81\xa2\xbc\xe8\x28\x90\x90\xd8\x56\x52\xab\xa3\xdc\x43\x8f\x17\x69\x28\x7b\xc2\x5b\xb5\xe1\x9e\xd6\x54\x1a"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\x53\x9d\x5c\xbb\x60\x73\x9e\x15\x21\x96"[..],
                &digest[..10]
            );
        }

        {
            let mut hmac = Hmac::<Sha1>::with_key(
                &b"\x2b\xaa\x67\x31\xc3\x67\xe0\xf8\x18\xab"[..],
            );
            let mut digest = vec![0u8; 20];

            hmac.update(&b"\xa6\x4e\xc0\xd9\x33\x60\x97\x6b\x75\xf5\x0e\xa5\x32\xc3\xd5\x01\x46\x4a\x39\x2c\x00\xab\xa5\x72\xc9\xbd\x69\x77\x06\x5e\xbb\x29\x40\x07\xfb\xf2\x82\xa4\x3c\x32\x03\xa2\xff\xec\x05\x49\x41\xc0\xfd\x4c\xb9\x19\xf4\x9e\x5b\xa7\x2d\x88\x20\x10\x08\xf9\x09\xe2\x26\x1d\x62\xcd\xce\x30\x44\x0f\x90\x95\x5d\x2f\x28\x22\xf3\xee\xa5\xbf\x27\x7b\xca\x2f\x77\xe6\xb4\x2d\x87\xd7\xbd\xbb\x21\x80\xa1\xb7\x7a\xd0\xdf\xaf\xb7\xe9\x62\xf6\xaf\xd5\x61\xf7\xf3\x74\x84\xca\x0c\xb9\x48\x05\x03\x16\xa4\xd5\x27\x35\xed\x4d\x0a\xe9"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\x2d\xdc\x8c\x48\x03\xe5\xa4\xc7\x87\x1c"[..],
                &digest[..10]
            );
        }

        {
            let mut hmac = Hmac::<Sha1>::with_key(
                &b"\xc1\xf4\xf1\xac\x1a\xdf\x93\xdf\x6e\x58"[..],
            );
            let mut digest = vec![0u8; 20];

            hmac.update(&b"\x5f\x45\x86\x57\xda\x5a\xec\x73\xd8\xaa\x5e\x34\x8b\xed\xc6\xaf\x48\x73\x41\x59\x3a\x0a\x74\x12\x56\x22\x23\x62\x91\x2f\xff\x02\x51\x4f\xc0\x9e\x22\x2d\x74\xd9\xab\x25\x17\x92\xe0\xa9\x63\x65\x79\xe3\xe9\x75\xa2\x9b\x61\x69\xf4\x5c\x3f\xb5\xa4\xd2\x87\x1b\xfa\x77\xe1\x71\x05\x6f\xf0\xa4\x8e\xaf\xe0\xfd\x4a\x65\x3e\xa3\x53\x94\x0d\x62\xd9\xff\x16\xaa\x15\x49\x7f\xdb\x7f\x5a\x9f\xbf\x41\x05\x11\x58\xeb\xe7\x07\xdd\x68\x92\xe1\xff\x31\xeb\xff\x70\xc0\xd0\xd3\xa6\x48\xfe\x3a\xdd\xa3\x32\x0c\x5b\x8c\x8f\xf1\xf7"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\xc1\xeb\xf8\x96\xbd\x26\xa3\x0c\xf6\x68"[..],
                &digest[..10]
            );
        }
    }

    #[test]
    fn cavp_sha224() {
        {
            let mut hmac = Hmac::<Sha224>::with_key(&b"\x37\x14\x70\x78\x39\xda\xf7\x91\x22\xc7\x82\x41\x63\x51\x38\x5e\x88\xa8\x1d\x31\xc9\xf6\x41\xd8\xdc\xe5\x38\xe9\x0e\x63\xc9\x58\x92\xa2\xea\x9b\x19\x62\xed\x0b\xa3\x72\xf4\x8e\x94\x74\xaa\x73\x0a\xe2"[..]);
            let mut digest = vec![0u8; 28];

            hmac.update(&b"\x41\x18\x43\xa2\x13\x87\x84\x6f\x3b\x9e\xd5\xfc\x54\x5a\xca\xdf\xa5\xb7\x03\x86\xf6\x2d\xa4\xd9\xa2\x7b\x04\x1b\xee\xa3\xaa\x11\x99\x36\x75\x67\xb4\xd1\x1a\x4f\xb4\xe8\xd4\x6b\xc6\xc2\x56\xed\x62\xc5\x05\xfd\x23\xf4\x64\x5b\xd6\xb6\xcf\x45\xd1\xd9\x6d\x9b\x86\xd6\x60\x41\x57\x57\x3e\xc5\xac\xf6\xc5\x41\x43\x48\xca\x83\xc8\x1a\x73\x6c\xa6\xfa\xa6\x96\x1c\xfa\xc1\x39\x93\xb0\x8c\x50\x2f\x81\x6c\xf7\xa4\x20\xd9\x18\x4b\x51\x11\x46\x75\xf3\x0e\xe9\xff\x3d\xb6\x9c\x26\x48\x53\xd3\x9d\xcd\x42\xc1\xdd\x31\xef\x79"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\x33\xf1\x7a\xc8\xa5\xc6\xb5\x25\xdb\x8b\x86\x44\xb6\xab"[..],
                &digest[..14]
            );
        }

        {
            let mut hmac = Hmac::<Sha224>::with_key(&b"\xce\x4c\x92\x6c\x09\x22\xba\x36\x26\x9a\x20\xd6\x0d\xcf\x08\xd4\x3a\x1c\xea\x12\x0f\x26\x6a\xf7\x6f\x1c\x8a\xcd\x88\x3d\x1f\x68\xf0\x9b\x82\x09\xf4\x1f\x87\x82\x2d\xce\xb3\x9a\x54\x4a\xa9\xb2\x56\x9c"[..]);
            let mut digest = vec![0u8; 28];

            hmac.update(&b"\x41\x0a\xc8\x70\x3f\x31\x2f\xe4\x26\xf0\xd1\xa6\x2d\x36\x2d\x44\x78\x25\x2f\x11\xdf\xc7\x0b\x78\xf0\xfc\x6c\x91\x37\xb7\xce\xf2\xbd\x6a\x28\xc8\xce\xbf\xcf\x26\xff\x89\x97\x9c\x70\xfa\x3b\x0c\x4f\x16\xff\xb9\x9d\x67\x93\xa1\x35\xf3\x3b\x0d\x0a\x6b\x2d\x66\xb0\xa5\x3a\x4a\x1e\x4c\xb1\xdf\xb2\xd7\x81\x67\x75\xb7\x9d\x15\xa1\xd5\xa5\x1f\x60\x3b\xc2\x15\xd7\x11\xd2\x71\x63\xcc\xc5\x6f\x22\xa2\x46\x1f\xb6\x41\x9e\xb8\x45\xc0\xd6\x2f\xc4\xd6\x1c\x08\x76\x4a\x69\x6d\xaf\xaa\x60\x7d\xde\x40\x78\xe6\xca\x42\x5d\xb6"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\x90\x08\x42\xbb\x91\x6f\xb0\xdf\xf7\xab\xe3\x7e\xd8\xf6"[..],
                &digest[..14]
            );
        }

        {
            let mut hmac = Hmac::<Sha224>::with_key(&b"\x54\x3a\x1e\x5d\xc9\x38\x44\xc8\x36\x2e\xec\x72\x94\x3e\x7f\xae\x3e\x66\xd4\x8b\x55\x54\xae\x4c\x63\x7c\x86\x18\x3e\x67\x8b\xf3\x30\x4e\xe8\xed\x54\xe7\x45\x99\x43\x7f\x90\xc1\xf0\x49\xfd\x58\xd1\xf6"[..]);
            let mut digest = vec![0u8; 28];

            hmac.update(&b"\xa5\xe1\xaa\x46\x37\x03\xf6\x8b\x32\xfe\x85\xa0\xee\x16\x98\x92\xda\x4e\x39\x11\x70\x89\xce\xbd\x68\xf0\xef\xa1\x2c\x93\x75\xfd\x8d\x53\xd3\x49\xb4\xff\xaa\x76\x5b\xbd\x97\x77\x3d\xac\x50\x00\xca\xc7\xef\x8e\x20\x0d\x8d\xa7\x37\xdf\x13\x63\x5b\xa9\x4d\x2b\xe0\xc4\x40\xc1\x11\x9b\xbe\x80\x69\x0d\x37\xe6\x06\x13\xd2\x4f\x5a\xa3\xbc\x03\x24\xd4\xc0\x73\x9e\x42\x19\xc0\xf8\xb4\x84\x7d\x06\xfc\x99\xb6\x36\x1f\x5a\x31\xc4\xb6\x0d\xf3\x31\x94\x47\x06\xf1\xa9\x4a\x7a\x64\x26\x90\xaa\x07\xe2\xa8\xc1\xec\xfd\x41\x7c"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\x73\x33\xe3\x65\xfc\xc3\xab\x2e\x51\x10\x14\x4e\x62\xab"[..],
                &digest[..14]
            );
        }

        {
            let mut hmac = Hmac::<Sha224>::with_key(&b"\xdc\x57\xaf\xb9\x18\x74\x27\x28\x86\x3d\xd8\x36\x3a\xc3\x9d\x22\x0c\xd2\x25\xab\x48\xd1\x49\x1b\xa7\xea\x9c\x84\x7e\x6b\x44\x4a\x36\x6c\x09\xe1\xfc\xb3\xac\xd8\xb9\xd4\x7a\x17\x45\x9c\x20\x65\xd8\xb0"[..]);
            let mut digest = vec![0u8; 28];

            hmac.update(&b"\xf7\x91\xbe\x39\xf3\xb7\x42\x08\xb3\x27\x20\x2b\x57\x56\x82\x70\x84\x24\x60\x45\xfb\x19\xac\x1f\x71\xee\xcd\x1c\x9b\x4f\x4f\xe7\x88\xdf\xd9\xdc\x33\x7d\x5f\x6c\x59\xc6\x98\xc3\x88\xda\xb3\xa9\x79\x63\x46\xa6\x9f\xd4\x87\x6a\x00\xef\xbe\x6b\x44\x8a\xfa\xd0\x0b\x92\x03\x8e\x84\x50\x91\xd1\x3c\xeb\xbb\x9d\x33\x2f\xb2\xb5\x35\x8c\xaf\xbc\x67\x62\x2a\x9a\x21\x7c\x4d\x21\xfb\xda\xa8\xf1\x2b\xb3\x26\x98\x0e\xba\x40\xfe\x04\xa1\x70\x01\x81\xdb\xe9\x5c\x61\xa7\x85\xcd\x7c\x4a\xff\x77\x7b\x9b\x62\x85\xea\xc5\xc1\x10"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\x03\xd7\x96\x76\x59\xbc\x07\xf2\x87\xf2\xe4\x7d\x8e\x30"[..],
                &digest[..14]
            );
        }

        {
            let mut hmac = Hmac::<Sha224>::with_key(&b"\x06\xe7\x21\x0d\xef\x08\x6f\x58\xb2\x10\xa7\x01\x06\x68\xe0\xd2\x5c\x52\xa4\x42\x1c\x1f\x4f\x48\x32\xa3\xb8\x71\xc9\xe6\x13\x31\x56\x1c\x16\x76\xd9\xd7\x5b\x83\x60\x7c\x06\xfc\xcc\xf3\xa7\x3d\xd7\xa3"[..]);
            let mut digest = vec![0u8; 28];

            hmac.update(&b"\xce\x7b\xe9\x70\xd6\x62\x72\x56\xe2\x45\xfc\x65\xec\xc0\xfc\x50\xab\x41\x7b\x0b\x15\x78\xbc\xdc\x23\x08\x1f\xb5\xd4\x83\x45\xc1\x74\x95\x75\x3d\x1e\x7f\x3e\x89\x80\xc7\x5e\x7f\xde\x2e\xe3\x03\x59\xe3\x90\xdb\x72\xf6\x82\xc2\xca\x0f\x14\xb7\x2b\x60\xff\x9b\xcc\xd8\xc6\xfb\xd1\x9a\x51\x2b\x12\xad\xd7\x94\x1d\xf5\x02\x4e\x7e\x62\x4e\xf2\x3e\x67\xb3\xa9\xa9\xae\x83\x89\x54\x0a\x95\x22\x5f\xad\xa3\x53\xf8\x9b\xf1\x63\x20\x5e\x2f\x4c\xb2\xfb\xa1\x5a\xa1\x26\x7d\xf5\x81\xb2\x95\xbb\x49\x4b\x35\xd3\x57\x67\x4f\x7d"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(
                &b"\xc5\x00\x41\x35\xb9\xbb\x6d\x83\x64\x30\x55\x03\xf7\x03"[..],
                &digest[..14]
            );
        }
    }

    #[test]
    fn cavp_sha256() {
        {
            let mut hmac = Hmac::<Sha256>::with_key(&b"\x6f\x35\x62\x8d\x65\x81\x34\x35\x53\x4b\x5d\x67\xfb\xdb\x54\xcb\x33\x40\x3d\x04\xe8\x43\x10\x3e\x63\x99\xf8\x06\xcb\x5d\xf9\x5f\xeb\xbd\xd6\x12\x36\xf3\x32\x45"[..]);
            let mut digest = vec![0u8; 32];

            hmac.update(&b"\x75\x2c\xff\x52\xe4\xb9\x07\x68\x55\x8e\x53\x69\xe7\x5d\x97\xc6\x96\x43\x50\x9a\x5e\x59\x04\xe0\xa3\x86\xcb\xe4\xd0\x97\x0e\xf7\x3f\x91\x8f\x67\x59\x45\xa9\xae\xfe\x26\xda\xea\x27\x58\x7e\x8d\xc9\x09\xdd\x56\xfd\x04\x68\x80\x5f\x83\x40\x39\xb3\x45\xf8\x55\xcf\xe1\x9c\x44\xb5\x5a\xf2\x41\xff\xf3\xff\xcd\x80\x45\xcd\x5c\x28\x8e\x6c\x4e\x28\x4c\x37\x20\x57\x0b\x58\xe4\xd4\x7b\x8f\xee\xed\xc5\x2f\xd1\x40\x1f\x69\x8a\x20\x9f\xcc\xfa\x3b\x4c\x0d\x9a\x79\x7b\x04\x6a\x27\x59\xf8\x2a\x54\xc4\x1c\xcd\x7b\x5f\x59\x2b"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\x05\xd1\x24\x3e\x64\x65\xed\x96\x20\xc9\xae\xc1\xc3\x51\xa1\x86"[..], &digest[..16]);
        }

        {
            let mut hmac = Hmac::<Sha256>::with_key(&b"\x17\xb5\x28\x58\xe3\xe1\x35\xbe\x44\x40\xd7\xdf\x0c\xa9\x96\xf4\x1c\xcb\x78\xb7\xd8\xcc\x19\x24\xd8\x30\xfe\x81\xe0\xfd\x27\x9c\x13\x1c\xe3\x54\x63\x03\xe9\x5a"[..]);
            let mut digest = vec![0u8; 32];

            hmac.update(&b"\xe0\xef\xf0\x0f\x3c\x46\xe9\x6c\x8d\x5b\xd1\x81\x28\x3e\x46\x05\x34\x8e\x3f\xa1\x0b\x47\x94\x5d\xe3\xdc\xc1\x59\xae\x86\xe7\xbd\x3f\xdb\x13\xf2\xad\xa2\xc3\x13\xfc\xe6\xa6\x9e\xfa\x49\xa4\x70\x68\x9b\x1e\xf0\x5a\xab\x77\x8a\xe1\x5d\xd3\x5f\xe6\xfd\x1e\x3a\x59\xd3\x51\xc6\x8c\xf8\xf0\xff\xd9\x68\xd7\xe7\x8b\x57\x37\x7a\xfc\xc9\xdc\xe3\xfa\x5d\xb1\xf0\x6f\x69\x85\xc4\x41\x4c\x0f\xcc\x78\x00\x30\xf4\x9f\xef\x79\x1a\x6c\x08\xed\xc2\xa3\x11\x08\x0c\x37\x3f\x00\xe4\xb2\x04\x4a\x79\xd8\x28\x60\xf0\x87\x1b\xc2\x59"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\xc4\x06\x14\x27\x76\x4f\x97\x94\x68\xac\x42\x28\x91\xde\xa9\xca"[..], &digest[..16]);
        }

        {
            let mut hmac = Hmac::<Sha256>::with_key(&b"\x7c\x67\x41\x0e\x0a\x9e\x3d\x7a\xe4\xf3\xd0\x4e\xff\x1c\x27\x16\x89\x1e\x82\x1c\x6e\xc1\xdc\x82\x21\x42\xce\x8d\x99\x49\xb1\x44\x9a\x1a\x03\x3a\x35\x0f\x0b\xa8"[..]);
            let mut digest = vec![0u8; 32];

            hmac.update(&b"\xbf\xd1\x66\x79\x3a\xbd\xcf\xfb\xbd\x56\xdf\x76\x91\x50\xd1\x46\x6c\x18\xa6\x7a\xf4\x52\xc7\xe6\x7f\x86\xed\x74\x1d\x16\x3e\xbb\xd8\x74\xb9\xd3\x3a\x91\xd3\x67\x10\x99\x62\x0b\x6e\xdd\xbb\xd0\xf3\x11\x17\x16\x4e\xb7\x3c\xa2\x01\xdb\x59\xf1\x65\x01\x31\xcb\xef\x5c\x7b\x1b\xb1\x40\x89\xfd\x24\xda\x29\x19\x24\x1f\xc9\x30\x3c\x02\xde\xf4\x24\xea\x86\x1d\x88\x63\x6b\xb9\x0b\x13\xeb\xc3\x8c\xf1\x77\xf8\xa8\xb1\x39\xe6\x80\x82\xfa\x46\xbc\xfc\x42\x8b\xd0\x54\xc1\xbb\x7d\xd3\xed\x7e\x9b\x86\xed\x75\x17\x36\xb6\xcc"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\x1a\x0d\x42\x7e\x79\xa7\xbd\xca\x7b\x11\x57\x93\x39\xd0\xff\x77"[..], &digest[..16]);
        }

        {
            let mut hmac = Hmac::<Sha256>::with_key(&b"\xb2\xc4\x50\x12\x8d\x07\x44\x42\x1c\x3f\x31\xfa\xb3\x7b\xbc\xdf\xb5\xa2\xff\x2f\xb7\x06\xd1\xf7\xe2\x3c\x48\x86\x99\x2c\x7d\x21\x5c\x64\x8f\xf8\xed\xb2\xeb\x59"[..]);
            let mut digest = vec![0u8; 32];

            hmac.update(&b"\xf6\x98\x9e\xbb\x07\xaa\xda\xee\xf9\x70\xf0\xb5\xce\xb8\x06\xec\xff\xe7\x7c\xc2\x0f\x3c\x22\x1a\x66\x59\xa9\x31\x5d\xff\x58\x81\x96\x19\x00\xe6\x8e\xfc\x32\x00\x75\xed\xaf\xd8\x3d\xe3\x20\xc6\xf1\x8f\x08\x92\x48\x9a\xf6\xd9\x7a\x2e\xff\xb2\x52\xb7\x6b\x92\x84\xeb\xaf\x6d\x42\x08\x9c\x1e\x0a\x5c\xd5\x09\xc2\x0b\x86\xff\x06\x0d\x53\x62\xc1\x76\x8f\x89\xfa\xfa\xaf\x65\xf1\xb0\xfe\x65\x6b\x16\x92\x98\x4a\x56\x7e\x12\x60\xc7\x49\x90\x85\xb7\x9f\x5f\xe7\x68\x47\x79\xa2\x58\x55\xf2\x91\xc5\xa1\x92\x63\x71\x77\xc4"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\xf0\xd7\xc6\x36\x77\x03\x3a\xda\x0b\x50\x2a\x4e\x95\xb2\x0e\x43"[..], &digest[..16]);
        }

        {
            let mut hmac = Hmac::<Sha256>::with_key(&b"\xa7\x74\x43\x21\xd7\x39\x38\xb8\xee\xa1\x37\x54\x90\x90\x29\x88\x1b\xbd\x72\x74\x39\xfe\x27\x31\xb1\xc6\x7b\x70\x83\xeb\x7b\x5d\x33\xad\xfc\xca\x65\xf5\xd1\x89"[..]);
            let mut digest = vec![0u8; 32];

            hmac.update(&b"\x71\x29\x9c\xa3\xda\xff\x23\x31\x08\x2d\xb3\x70\xbd\xf8\xce\xec\x22\x7b\x71\xbd\xc4\x9c\x3b\x14\xdc\x3f\xd2\x13\xd3\xba\x83\xe2\x05\x88\x28\xff\xc6\x41\x4f\xd5\xa2\xc9\x98\x91\xe9\xc8\x5f\x31\x6c\x5b\x9b\xdd\x81\x0a\x06\x7b\x4d\xf9\x7f\x7e\x42\x62\xac\xfe\xe6\x42\xe3\x0e\xd6\x53\x4b\x4a\x0b\x3b\x3e\xaf\x5d\x03\xf2\xb0\x45\xca\x59\x85\xe7\xbb\x45\xc7\x50\x3c\xd0\x3a\xfc\x68\xfb\xea\x9b\xc0\x95\x79\x14\x1d\x5f\xb7\xcb\xea\x6d\x73\x20\x8f\xcf\x91\x38\x30\x71\x5d\xff\x98\x40\x1f\x6d\x70\x8e\xf0\x09\xb5\xb8\xcb"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\xf6\x30\x2c\x5f\xd7\xc8\x49\x5e\x23\x3b\x5d\x61\x29\xf3\x61\xda"[..], &digest[..16]);
        }
    }

    #[test]
    fn cavp_sha384() {
        {
            let mut hmac = Hmac::<Sha384>::with_key(&b"\xf1\x6a\xd7\x37\x90\xca\x39\xc7\xf9\x85\x6c\x44\x83\x20\x2e\x7f\x8e\x0c\x82\x83\xc7\xd5\x0d\x6d\xa7\x9c\xc0\x7d\x3d\xc7\xb7\x6c\x2e\xf7\x61\x00\xfa\x3a\xe2\xdf\x80\x83\xb5\xa1\xc5\x57\x96\x28\xf1\xc8"[..]);
            let mut digest = vec![0u8; 48];

            hmac.update(&b"\x98\x70\x00\x76\x54\xeb\xc3\xd2\x8f\x88\x3b\xb8\x32\xe0\xb3\x17\x00\xf9\x23\xd9\xc9\xb1\x01\x68\xe0\x60\x59\x71\xcf\xb9\x20\xe8\x48\xf1\xc6\x4c\x5f\x24\x0a\x2c\xf7\xf4\x12\xea\x7a\x73\xbb\xbf\xce\x43\x2e\xff\x84\xfb\xb4\x9e\x52\xcd\xcb\xf4\xc3\x66\x79\xbd\x2d\x16\xe0\x64\xe4\x31\x13\x81\xad\xb5\x28\xa0\x75\x2c\x8e\x44\x43\xd4\xa1\x2b\x6c\xfe\x7c\xd4\x06\xb4\x0e\x3f\x9e\x9e\x71\xf4\x2e\x27\x76\x46\x49\xdb\x85\xd9\x99\x13\xa4\x62\x8b\xd5\xd5\xae\x49\xf6\xa5\xe6\xe9\x81\x02\x11\xe3\x5d\x4d\xda\xc9\x29\xb0\x93"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\x79\xe2\x4a\x20\x3b\xf4\x20\x74\xe7\x2c\x8b\x4a\x02\x22\xaf\xac\xe3\xe8\xce\x7b\x40\x04\xce\xc2"[..], &digest[..24]);
        }

        {
            let mut hmac = Hmac::<Sha384>::with_key(&b"\xa5\x70\x9b\xa5\x52\x9c\xb9\xa1\xa2\x27\xf0\xbe\x44\x8e\x11\x9a\x35\x6f\x92\xe1\x3e\xfc\x34\x63\xbe\xaa\xe4\x6a\xa9\x29\xdf\x4a\xd1\x99\x1a\x39\x64\xfb\xe1\x61\xb6\xe5\xbe\x34\x41\x7a\x9c\x00\xeb\x9a"[..]);
            let mut digest = vec![0u8; 48];

            hmac.update(&b"\x4f\x56\x9d\x60\x40\x56\x63\xff\xd4\x89\x37\x77\xcb\xc3\x71\x55\xd4\x03\xe2\xb0\xf5\x48\x5d\xa4\x2c\xa6\x75\x03\x57\x98\x89\x46\x51\x98\xfe\xca\x5e\xed\xcc\x39\xc9\xc5\x3c\x45\xcb\x83\xf0\x9d\xaf\x5a\x23\x19\x34\x1b\x32\x38\x33\x4b\x5b\xcd\x81\x79\xc5\xf5\x17\xce\xc1\x4c\x70\xe6\x50\x61\x33\xde\xe5\x67\x12\xaf\x6c\x2d\xf2\xba\x8a\x50\x4c\xa4\x27\xaf\xd3\x63\x2a\x1f\x57\x99\x83\x60\xe9\x21\x6f\x50\x40\xe8\xf7\x5f\x5b\xff\xba\x43\x68\xee\xed\xed\xe5\x4a\xa0\xbb\x05\x8a\x43\xef\x55\x16\x68\x60\x9f\xa1\xcb\x6f"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\x24\x7e\xb5\x1a\x39\x7b\xa3\x69\xec\xba\x43\xb9\x5a\x46\xa9\x33\xcf\xf0\xb1\x00\x57\x14\xf0\xe5"[..], &digest[..24]);
        }

        {
            let mut hmac = Hmac::<Sha384>::with_key(&b"\x18\x7c\x04\x7e\x4e\xd5\x49\x03\x05\x22\x53\x55\xfb\xb3\x81\x68\x29\x32\x24\x5b\x01\xda\xe0\x4d\xf5\xe4\x56\x72\x38\x42\xff\x66\xc8\x90\x5b\xc1\xac\x48\x4c\xeb\x7a\x35\xbc\x32\x1d\x2a\x86\x19\xd5\xf3"[..]);
            let mut digest = vec![0u8; 48];

            hmac.update(&b"\x16\x26\x3d\xd9\x50\x36\x12\x81\x19\xd7\x81\x86\x5e\x4f\x81\x8a\x86\x7b\x50\x66\x55\x1e\x71\x1f\x11\x79\xf6\x16\xe4\x1c\xfb\x7e\x82\xfb\x73\x13\x0b\xc4\x27\x09\x33\x70\xfb\x43\xa0\x19\x73\xc6\x94\x0b\x77\x6d\xcb\x1d\x53\xde\xa7\x42\x02\xbc\x8a\x5b\xac\x1f\x83\x4f\x6d\x41\x2e\x5e\x58\x7a\xd5\xb2\xbc\x6e\xdb\x37\xa5\x85\x5b\xad\xa6\x9b\x0c\xfc\xd6\xf9\x68\xc7\x19\x84\x0d\x43\xa1\x35\x63\x4a\xb4\xc9\x7f\xab\xaf\xba\x47\xc5\x4b\x6d\xd7\x54\x1f\xad\x24\x8a\x66\x58\xdf\x62\x03\x58\x9d\x31\xc2\xd5\x34\x7d\xe1\xa9"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\x74\x11\x8d\x1b\x4c\x60\xc9\xdd\x70\x29\x82\x9e\x27\x98\x7f\x40\xaa\x9f\xa5\x4b\x7f\x9c\x0c\x00"[..], &digest[..24]);
        }

        {
            let mut hmac = Hmac::<Sha384>::with_key(&b"\x07\xc6\x45\x41\xd0\xcc\x4c\x23\x85\xdf\xc4\xe7\xf4\x9d\xa4\x39\x6d\x2c\x4a\x8d\xde\xce\xc0\x58\x3d\xb6\x3d\x7f\x26\x1b\xef\x0f\xc6\x8a\xf7\x30\xf7\x80\xb6\x54\xac\x38\x47\xb4\x90\xc2\x4c\xfd\xea\x55"[..]);
            let mut digest = vec![0u8; 48];

            hmac.update(&b"\xf7\x45\x7e\x98\x68\x55\x64\xe3\xd3\x6b\x5a\x9a\x23\x59\x39\x43\x98\xeb\xeb\x2e\x0f\x1d\xd1\x4d\x84\x8b\x62\x45\xd5\x29\x15\xc5\xc8\x34\x81\x17\x50\x69\xc3\xf5\x0c\x74\x21\x9d\x11\xab\xed\x28\xe9\xfc\xab\x17\xdb\x24\x76\x2f\x6d\x22\x9f\x87\x28\xec\x98\xdf\x9b\x60\x10\x33\xa3\x7d\x60\x90\xe9\xd3\x26\x27\xab\x38\x2f\xa0\xc0\xbd\x9b\xb0\xd6\xe1\x3b\xee\xff\x04\x3e\xe2\x6c\x1e\x0d\x5f\x77\xb0\x73\x13\xe7\xfb\x01\x5d\x70\x71\xb1\x5e\x7a\x69\xc9\x53\x24\x16\x02\x22\x87\xba\xea\x32\x3f\x17\x87\x80\x28\x26\x3d\xf0"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\x22\xe1\x6e\xa2\xa8\xa7\x37\x73\x89\xf2\x3f\x92\xe1\xb6\x89\x55\x50\x15\xf2\xa5\xf2\xe3\xc8\x7d"[..], &digest[..24]);
        }

        {
            let mut hmac = Hmac::<Sha384>::with_key(&b"\x36\x5b\x14\x5e\x50\x7e\x97\x52\x40\x88\x29\xc6\x9c\x87\x32\xda\x16\x35\x14\xb3\x51\x7a\xa6\x1d\xf3\x31\xe4\x74\xfc\x2f\xe5\xc4\x56\x81\x0d\x2f\xac\xf6\x83\x8f\x80\xde\xe5\x5d\x78\x10\x3b\xd2\xf9\x32"[..]);
            let mut digest = vec![0u8; 48];

            hmac.update(&b"\x63\x7d\x20\x92\xa1\xf5\x62\x0f\xa2\xca\x9f\x65\xb1\xa7\x22\xc9\xfe\x92\x30\x7a\x9e\xd6\x2f\x52\xd4\x41\x0e\x9a\x8f\x90\xe0\x23\x33\x28\xca\x92\x9c\x07\x20\xfc\x61\xf9\xcb\xb3\x55\x0f\xee\x5f\x54\x4d\xc9\x50\x3c\xa3\xdd\x12\x39\x1f\x50\x42\x46\x60\x94\xa1\xf0\x4e\x44\x67\x5d\x08\x4e\xda\x8e\x1e\x57\x1e\xe1\x01\x5b\x4f\xda\xb7\x94\xcd\x22\xd3\x9e\xd7\xd0\xa5\xd8\x5c\xe8\xae\x0d\x0d\x21\x56\x54\xb7\xec\xe2\x34\xd0\xb1\xa0\x0c\x50\x5c\x64\xb2\xc2\x18\x38\x5b\x9a\x5a\x50\xbb\xc9\x22\x3c\x6d\x8f\x7e\x61\x94\x90"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\xa0\x16\x27\x4a\x2e\x32\x02\x54\x7b\xe4\xf9\xa3\x83\x0b\x2b\x8e\xec\x39\xdc\xdf\xd1\xa8\xca\x7c"[..], &digest[..24]);
        }
    }

    #[test]
    fn cavp_sha512() {
        {
            let mut hmac = Hmac::<Sha512>::with_key(&b"\x72\x63\x74\xc4\xb8\xdf\x51\x75\x10\xdb\x91\x59\xb7\x30\xf9\x34\x31\xe0\xcd\x46\x8d\x4f\x38\x21\xea\xb0\xed\xb9\x3a\xbd\x0f\xba\x46\xab\x4f\x1e\xf3\x5d\x54\xfe\xc3\xd8\x5f\xa8\x9e\xf7\x2f\xf3\xd3\x5f\x22\xcf\x5a\xb6\x9e\x20\x5c\x10\xaf\xcd\xf4\xaa\xf1\x13\x38\xdb\xb1\x20\x73\x47\x4f\xdd\xb5\x56\xe6\x0b\x8e\xe5\x2f\x91\x16\x3b\xa3\x14\x30\x3e\xe0\xc9\x10\xe6\x4e\x87\xfb\xf3\x02\x21\x4e\xdb\xe3\xf2"[..]);
            let mut digest = vec![0u8; 64];

            hmac.update(&b"\xac\x93\x96\x59\xdc\x5f\x66\x8c\x99\x69\xc0\x53\x04\x22\xe3\x41\x7a\x46\x2c\x8b\x66\x5e\x8d\xb2\x5a\x88\x3a\x62\x5f\x7a\xa5\x9b\x89\xc5\xad\x0e\xce\x57\x12\xca\x17\x44\x2d\x17\x98\xc6\xde\xa2\x5d\x82\xc5\xdb\x26\x0c\xb5\x9c\x75\xae\x65\x0b\xe5\x65\x69\xc1\xbd\x2d\x61\x2c\xc5\x7e\x71\x31\x59\x17\xf1\x16\xbb\xfa\x65\xa0\xae\xb8\xaf\x78\x40\xee\x83\xd3\xe7\x10\x1c\x52\xcf\x65\x2d\x27\x73\x53\x1b\x7a\x6b\xdd\x69\x0b\x84\x6a\x74\x18\x16\xc8\x60\x81\x92\x70\x52\x2a\x5b\x0c\xdf\xa1\xd7\x36\xc5\x01\xc5\x83\xd9\x16"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\xbd\x3d\x2d\xf6\xf9\xd2\x84\xb4\x21\xa4\x3e\x5f\x9c\xb9\x4b\xc4\xff\x88\xa8\x82\x43\xf1\xf0\x13\x3b\xad\x0f\xb1\x79\x1f\x65\x69"[..], &digest[..32]);
        }

        {
            let mut hmac = Hmac::<Sha512>::with_key(&b"\xe2\x45\xbe\x9a\x9c\x81\x01\x26\x38\x30\xad\x35\x15\xc1\xc6\xcb\xf2\x85\xa7\xe4\xb3\x62\xeb\xc0\x62\xcb\x8e\x7e\x75\xef\x50\xec\x4f\x31\x5a\x9e\x09\xd9\x24\x3d\x71\x09\x96\x22\x53\xf2\x6e\x23\xf8\x47\xe1\xad\xed\xf2\x85\x14\x05\x07\x6e\x26\xa1\xf6\x97\x06\x2f\x04\x84\x38\xf1\xfc\x26\xf8\x00\x21\xff\xd0\x90\x68\x87\x69\x75\xe4\xcd\xa2\xe7\x82\x61\xdf\x82\xf6\x72\xa3\x90\xf5\x34\x62\x8b\xa5\x84\x90"[..]);
            let mut digest = vec![0u8; 64];

            hmac.update(&b"\x42\x53\x15\xdd\x8e\xcc\xd1\x7a\x84\xc1\xaa\x00\xff\x72\x76\x3f\x99\xdd\xcb\xc2\xc3\x81\xb8\xb2\x15\x67\xb2\xf8\xe2\x63\xd1\xa2\x10\x98\x3d\x88\x26\x3a\xe3\x2f\xa7\x98\x6c\xed\x9f\x59\x6f\x4e\x7b\x05\xe5\xb7\x1d\xc8\xde\x49\x30\x73\x73\x08\xb9\xc4\xfc\x3d\xef\xe7\x83\x19\x4d\x3c\x78\x9a\xe5\x5b\xa5\xb3\xf7\x56\x65\xa7\xc2\x3e\x11\xb6\x9a\xe8\xbc\xfb\x3b\xf0\x20\x95\x5d\xff\xd7\x05\x89\x4a\xcf\xd7\x2a\x5b\xf8\x85\xe7\x14\x3f\x98\x30\xf1\xc0\x10\x17\x8d\x37\x06\x62\x68\xb8\x90\xde\xe7\xa1\xe5\xf6\x9c\xcc\xc1"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\xc5\x80\x1d\x80\xa1\x43\x91\x72\x0e\x77\xeb\x7f\xfb\x1a\x0b\x21\xa1\x63\x23\x64\x1c\x9a\x31\x2b\x05\xfd\xc3\x4e\x90\x38\x3c\x85"[..], &digest[..32]);
        }

        {
            let mut hmac = Hmac::<Sha512>::with_key(&b"\x7e\xb7\x2f\x11\x7b\x39\x7c\xef\xcf\xb4\xe7\x5a\xce\x3b\x08\x17\x76\xe4\x6b\x13\x52\x1e\x93\x55\x9d\x45\x3e\x32\xab\x74\xeb\xc0\x85\x9b\x9a\x8d\xd4\xd1\xd3\x90\x00\xeb\xe9\x5f\x98\x4d\x80\xa3\xf5\x00\x4d\xc9\x1a\x05\x1d\xfb\xdf\xe9\x19\x4f\x4f\x9a\x48\x3e\x4e\x79\x55\x57\x7f\xb0\x93\x34\x64\xc6\x3e\xae\xc7\x71\x04\x4d\x59\xab\xc3\x02\x9a\x07\x95\x19\xf8\x46\x0a\x69\x3b\x25\xb4\xce\x20\x7a\xe9\xd9"[..]);
            let mut digest = vec![0u8; 64];

            hmac.update(&b"\x4e\x66\x11\xa6\xd7\x63\x95\xf2\xb0\xe2\x3d\xca\xfc\xc6\x72\xc0\x90\xe7\xc0\x0a\x5f\xb5\xe2\x3d\x35\x1f\x1f\x59\xa9\xb3\xda\x06\x4d\x06\x64\x1d\x27\x56\x14\x6a\x65\x6e\x9a\xb1\x4c\xca\x90\xee\x72\xfc\x52\xe1\x2d\x4e\x10\xca\x4b\xa9\x21\x72\x03\xb5\x9a\x6a\x2c\x42\x20\x97\xad\xe7\xfa\xef\x35\xe8\x6a\x7d\x2c\x5d\x3e\xab\xe9\x91\xa2\xc0\x25\xa9\x38\xa8\xaf\x86\x6b\xf4\x62\xec\x00\x21\x55\xe3\xed\x1d\x51\x5d\x6f\x07\x88\x1a\x57\x36\x83\xc9\xa4\x7e\x5d\x70\x57\xae\x2f\x0d\x83\x5d\xcb\x7e\xa4\xe7\xad\x9e\x31\xb2"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\x53\x1b\xb2\x08\x00\xce\xef\x73\x6d\x52\xd3\x23\xa0\x1f\x91\xfe\xd1\xb8\x04\x57\x94\x7b\x1f\x86\x5d\x1f\x6b\x3b\x11\x02\x55\x2f"[..], &digest[..32]);
        }

        {
            let mut hmac = Hmac::<Sha512>::with_key(&b"\x12\x72\x0c\xff\x0c\xa6\x49\xff\x2e\x1c\x93\x55\xcb\xa8\x02\x0f\xc9\x6d\xbe\x05\xaf\x9f\xb4\xbc\x00\x8d\x8d\x8a\xc8\xde\xe0\xfb\x74\x1a\xa6\x74\xe6\x6d\xef\x16\xc9\xa8\xd4\xe5\x22\x89\xad\x2a\x28\x3c\x84\x16\x56\x21\xc9\xa7\xbe\xd0\x46\xd0\xa0\x5b\x56\xd4\x3b\xd3\x52\xf3\xe3\x0d\x4d\x48\x54\xa5\x01\xf2\x46\x44\x08\x72\x42\x1f\x50\x54\xb3\xc0\xc9\x12\x40\x09\x60\x35\x59\x76\x31\xbd\x10\xa2\xf8\xc3"[..]);
            let mut digest = vec![0u8; 64];

            hmac.update(&b"\xde\xf8\xc9\xac\xee\x9d\x9f\x19\x14\x19\x98\x25\x51\x80\x4a\x9a\x94\x11\xc7\xd1\x24\x0b\x22\x24\x3d\xc3\x2f\xa5\xfe\xf2\x8b\x11\x83\x53\xdc\xff\x4e\x6e\x5a\x5d\xeb\xae\x8f\x1d\xd3\xba\x5a\x2c\x92\x02\x3a\xa4\x25\x98\xc9\x42\xa6\x42\x87\x1a\x2b\xcd\xd9\x89\xeb\xa4\x52\x6c\xa2\xa1\x30\x8f\x37\x22\x2a\x69\x9c\x60\x69\x06\xf7\xfc\xd4\x44\xff\xdb\x90\x42\xa8\x34\xc7\x16\x02\xe7\xa9\xbe\x5e\x11\xb1\x59\xb4\xdd\x2a\x98\x41\x9d\xf1\x6f\x74\x19\x7c\x10\x0b\x26\x1b\x19\x7a\x7b\x7e\x0c\x8c\xc1\x78\x01\x4c\xe9\x02\x97"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\xdc\x72\xf7\x04\x9c\x66\xef\xfc\xb8\x20\x84\x80\x59\x51\x6c\x44\xf9\x34\xcc\xb2\xff\xca\x6f\x9f\x8f\x88\x4e\x0e\x1c\x67\xee\xce"[..], &digest[..32]);
        }

        {
            let mut hmac = Hmac::<Sha512>::with_key(&b"\x83\x48\x8a\x05\x03\x29\x05\x75\x4c\xc8\xfc\x56\x9d\x37\xca\xe0\x5f\x0c\x37\x0d\xb6\xac\xaa\xfc\x56\xca\x9a\x93\x98\x2a\x46\x69\xcc\xab\xa6\xe3\xd1\x84\xa1\x9d\xe4\xce\x80\x0b\xb6\x43\xa3\x60\xc1\x45\x72\xae\xdb\x22\x97\x4f\x0c\x96\x6b\x85\x9d\x91\xad\x5d\x71\x3b\x7a\xd9\x99\x35\x79\x4d\x22\x22\x57\x0a\x31\x67\x73\x3a\x53\x2e\xda\x0b\x0e\xb1\x75\x10\xbc\xb5\x81\xe4\x99\x54\x40\x10\x1a\x00\xee\x2e"[..]);
            let mut digest = vec![0u8; 64];

            hmac.update(&b"\xbd\x11\x70\xaf\x91\xfd\xb2\x16\x0d\xb3\x52\x2e\x1b\xc3\xb1\xa3\x49\xd6\xe5\x04\x79\x92\x0a\xc5\xd9\xbe\xdd\x8a\x16\xa7\x87\xa3\xcd\xc2\xb6\xd2\x43\x92\xf2\x55\x55\xcc\x2f\x20\xb2\xba\x9e\x6b\x47\xdd\xc9\x6c\xfb\xd6\xdf\x66\x9d\x87\x4c\xe2\x1a\x75\x8d\x3c\xf4\x70\x43\x62\xef\x77\x86\xd9\x0e\xd6\x7b\x01\xbd\x91\x29\x99\x50\x05\x88\x85\xac\xcd\xdb\xcf\x44\xe3\x40\xed\x48\x07\x86\x42\x18\x65\x3e\xe7\xff\x72\x15\xaa\x1e\x17\x61\x57\xa6\x11\xf9\x37\x4b\x98\x4a\xd7\xf5\x3e\xa7\x0a\xb8\x1b\xe1\x31\x06\x27\x18\xba"[..]);
            hmac.digest(&mut digest).unwrap();
            assert_eq!(&b"\x65\x63\x09\x7d\xb0\x46\x30\x82\x1c\x81\x49\x12\x82\x84\x10\xd2\xcb\x05\x62\x19\xf8\x86\x78\x6d\x6b\xf5\x7a\x5b\x5b\x00\x83\xea"[..], &digest[..32]);
        }
    }
}