1use crate::cipher::aes::Aes;
80use crate::cipher::des::TripleDes;
81use crate::cipher::modes::{gf128_mul, ghash_update};
82use crate::hash::ripemd160::Ripemd160;
83use crate::hash::sha1::Sha1;
84use crate::hash::sha3::{KeccakState, Sha3_256, Sha3_384, Sha3_512};
85use crate::hash::sha256::Sha256;
86use crate::hash::sha384::Sha384;
87use crate::hash::sha512::Sha512;
88use crate::{BlockCipher, Hasher};
89
90#[derive(Clone, Copy, Debug, PartialEq, Eq)]
96pub enum Algorithm {
97 HmacSha1,
99 HmacSha256,
101 HmacSha384,
103 HmacSha512,
105 HmacSha3_256,
107 HmacSha3_384,
109 HmacSha3_512,
111 HmacRipemd160,
113
114 CmacAes128,
116 CmacAes192,
118 CmacAes256,
120 CmacTripleDes,
122
123 Kmac128,
125 Kmac256,
127
128 GmacAes128,
131 GmacAes192,
133 GmacAes256,
135}
136
137#[derive(Clone, Copy, Debug, PartialEq, Eq)]
139pub enum Error {
140 InvalidKeyLen,
142 InvalidNonceLen,
144 NotInitialized,
146 AlreadyFinalized,
149 OutputBufferTooSmall {
152 needed: usize,
154 },
155 WrongInitVariant,
158 VerificationFailed,
160}
161
162enum HmacState {
167 Sha1(Sha1),
168 Sha256(Sha256),
169 Sha384(Sha384),
170 Sha512(Sha512),
171 Sha3_256(Sha3_256),
172 Sha3_384(Sha3_384),
173 Sha3_512(Sha3_512),
174 Ripemd160(Ripemd160),
175}
176
177impl HmacState {
178 fn block_len(&self) -> usize {
179 match self {
180 HmacState::Sha1(_) => Sha1::BLOCK_LEN,
181 HmacState::Sha256(_) => Sha256::BLOCK_LEN,
182 HmacState::Sha384(_) => Sha384::BLOCK_LEN,
183 HmacState::Sha512(_) => Sha512::BLOCK_LEN,
184 HmacState::Sha3_256(_) => Sha3_256::BLOCK_LEN,
185 HmacState::Sha3_384(_) => Sha3_384::BLOCK_LEN,
186 HmacState::Sha3_512(_) => Sha3_512::BLOCK_LEN,
187 HmacState::Ripemd160(_) => Ripemd160::BLOCK_LEN,
188 }
189 }
190
191 #[allow(dead_code)]
194 fn output_len(&self) -> usize {
195 match self {
196 HmacState::Sha1(_) => Sha1::OUTPUT_LEN,
197 HmacState::Sha256(_) => Sha256::OUTPUT_LEN,
198 HmacState::Sha384(_) => Sha384::OUTPUT_LEN,
199 HmacState::Sha512(_) => Sha512::OUTPUT_LEN,
200 HmacState::Sha3_256(_) => Sha3_256::OUTPUT_LEN,
201 HmacState::Sha3_384(_) => Sha3_384::OUTPUT_LEN,
202 HmacState::Sha3_512(_) => Sha3_512::OUTPUT_LEN,
203 HmacState::Ripemd160(_) => Ripemd160::OUTPUT_LEN,
204 }
205 }
206
207 fn update(&mut self, data: &[u8]) {
208 match self {
209 HmacState::Sha1(h) => h.update(data),
210 HmacState::Sha256(h) => h.update(data),
211 HmacState::Sha384(h) => h.update(data),
212 HmacState::Sha512(h) => h.update(data),
213 HmacState::Sha3_256(h) => h.update(data),
214 HmacState::Sha3_384(h) => h.update(data),
215 HmacState::Sha3_512(h) => h.update(data),
216 HmacState::Ripemd160(h) => h.update(data),
217 }
218 }
219
220 fn hash_key(&self, key: &[u8]) -> Vec<u8> {
223 match self {
224 HmacState::Sha1(_) => Sha1::hash(key),
225 HmacState::Sha256(_) => Sha256::hash(key),
226 HmacState::Sha384(_) => Sha384::hash(key),
227 HmacState::Sha512(_) => Sha512::hash(key),
228 HmacState::Sha3_256(_) => Sha3_256::hash(key),
229 HmacState::Sha3_384(_) => Sha3_384::hash(key),
230 HmacState::Sha3_512(_) => Sha3_512::hash(key),
231 HmacState::Ripemd160(_) => Ripemd160::hash(key),
232 }
233 }
234
235 fn finalize_inner(self) -> Vec<u8> {
237 match self {
238 HmacState::Sha1(h) => h.finalize(),
239 HmacState::Sha256(h) => h.finalize(),
240 HmacState::Sha384(h) => h.finalize(),
241 HmacState::Sha512(h) => h.finalize(),
242 HmacState::Sha3_256(h) => h.finalize(),
243 HmacState::Sha3_384(h) => h.finalize(),
244 HmacState::Sha3_512(h) => h.finalize(),
245 HmacState::Ripemd160(h) => h.finalize(),
246 }
247 }
248
249 fn outer_hash(&self, opad_key: &[u8], inner_digest: &[u8]) -> Vec<u8> {
252 match self {
253 HmacState::Sha1(_) => {
254 let mut h = Sha1::new();
255 h.update(opad_key);
256 h.update(inner_digest);
257 h.finalize()
258 }
259 HmacState::Sha256(_) => {
260 let mut h = Sha256::new();
261 h.update(opad_key);
262 h.update(inner_digest);
263 h.finalize()
264 }
265 HmacState::Sha384(_) => {
266 let mut h = Sha384::new();
267 h.update(opad_key);
268 h.update(inner_digest);
269 h.finalize()
270 }
271 HmacState::Sha512(_) => {
272 let mut h = Sha512::new();
273 h.update(opad_key);
274 h.update(inner_digest);
275 h.finalize()
276 }
277 HmacState::Sha3_256(_) => {
278 let mut h = Sha3_256::new();
279 h.update(opad_key);
280 h.update(inner_digest);
281 h.finalize()
282 }
283 HmacState::Sha3_384(_) => {
284 let mut h = Sha3_384::new();
285 h.update(opad_key);
286 h.update(inner_digest);
287 h.finalize()
288 }
289 HmacState::Sha3_512(_) => {
290 let mut h = Sha3_512::new();
291 h.update(opad_key);
292 h.update(inner_digest);
293 h.finalize()
294 }
295 HmacState::Ripemd160(_) => {
296 let mut h = Ripemd160::new();
297 h.update(opad_key);
298 h.update(inner_digest);
299 h.finalize()
300 }
301 }
302 }
303}
304
305#[allow(clippy::large_enum_variant)]
310enum Inner {
311 None,
312 Hmac {
313 inner: HmacState,
315 opad_key: Vec<u8>,
317 },
318 Cmac {
319 aes: Option<Aes>,
321 tdes: Option<TripleDes>,
323 block_len: usize,
324 k1: [u8; 16],
326 k2: [u8; 16],
328 x: [u8; 16],
330 buf: [u8; 16],
333 buf_len: usize,
334 },
335 Kmac {
336 sponge: KeccakState,
339 out_len: usize,
341 },
342 Gmac {
343 aes: Aes,
345 h: [u8; 16],
347 e_j0: [u8; 16],
350 y: [u8; 16],
352 buf: [u8; 16],
354 buf_len: usize,
355 total_len: u64,
358 },
359}
360
361pub struct Mac {
370 algo: Algorithm,
371 inner: Inner,
372 initialized: bool,
373 finalized: bool,
374}
375
376impl Mac {
377 pub fn new(algo: Algorithm) -> Self {
382 Self {
383 algo,
384 inner: Inner::None,
385 initialized: false,
386 finalized: false,
387 }
388 }
389
390 pub fn init(&mut self, key: &[u8]) -> Result<(), Error> {
404 match self.algo {
405 Algorithm::GmacAes128 | Algorithm::GmacAes192 | Algorithm::GmacAes256 => Err(Error::WrongInitVariant),
406 Algorithm::Kmac128 | Algorithm::Kmac256 => self.init_kmac(key, &[]),
407 _ => self.init_internal(key, None, None),
408 }
409 }
410
411 pub fn init_kmac(&mut self, key: &[u8], custom: &[u8]) -> Result<(), Error> {
417 match self.algo {
418 Algorithm::Kmac128 | Algorithm::Kmac256 => self.init_internal(key, None, Some(custom)),
419 _ => Err(Error::WrongInitVariant),
420 }
421 }
422
423 pub fn init_with_nonce(&mut self, key: &[u8], nonce: &[u8]) -> Result<(), Error> {
433 match self.algo {
434 Algorithm::GmacAes128 | Algorithm::GmacAes192 | Algorithm::GmacAes256 => {
435 if nonce.len() != 12 {
436 return Err(Error::InvalidNonceLen);
437 }
438 self.init_internal(key, Some(nonce), None)
439 }
440 _ => Err(Error::WrongInitVariant),
441 }
442 }
443
444 fn init_internal(&mut self, key: &[u8], nonce: Option<&[u8]>, custom: Option<&[u8]>) -> Result<(), Error> {
445 self.inner = match self.algo {
446 Algorithm::HmacSha1
448 | Algorithm::HmacSha256
449 | Algorithm::HmacSha384
450 | Algorithm::HmacSha512
451 | Algorithm::HmacSha3_256
452 | Algorithm::HmacSha3_384
453 | Algorithm::HmacSha3_512
454 | Algorithm::HmacRipemd160 => {
455 let mut state = match self.algo {
456 Algorithm::HmacSha1 => HmacState::Sha1(Sha1::new()),
457 Algorithm::HmacSha256 => HmacState::Sha256(Sha256::new()),
458 Algorithm::HmacSha384 => HmacState::Sha384(Sha384::new()),
459 Algorithm::HmacSha512 => HmacState::Sha512(Sha512::new()),
460 Algorithm::HmacSha3_256 => HmacState::Sha3_256(Sha3_256::new()),
461 Algorithm::HmacSha3_384 => HmacState::Sha3_384(Sha3_384::new()),
462 Algorithm::HmacSha3_512 => HmacState::Sha3_512(Sha3_512::new()),
463 Algorithm::HmacRipemd160 => HmacState::Ripemd160(Ripemd160::new()),
464 _ => unreachable!(),
465 };
466 let block_len = state.block_len();
467
468 let mut key_block = vec![0u8; block_len];
470 if key.len() > block_len {
471 let hashed = state.hash_key(key);
472 key_block[..hashed.len()].copy_from_slice(&hashed);
473 } else {
474 key_block[..key.len()].copy_from_slice(key);
475 }
476
477 let mut ipad_key = key_block.clone();
479 let mut opad_key = key_block;
480 for b in &mut ipad_key {
481 *b ^= 0x36;
482 }
483 for b in &mut opad_key {
484 *b ^= 0x5C;
485 }
486
487 state.update(&ipad_key);
488 Inner::Hmac { inner: state, opad_key }
489 }
490
491 Algorithm::CmacAes128 | Algorithm::CmacAes192 | Algorithm::CmacAes256 | Algorithm::CmacTripleDes => {
493 let expected_key_len = match self.algo {
494 Algorithm::CmacAes128 => 16,
495 Algorithm::CmacAes192 => 24,
496 Algorithm::CmacAes256 => 32,
497 Algorithm::CmacTripleDes => 24,
498 _ => unreachable!(),
499 };
500 if key.len() != expected_key_len {
501 return Err(Error::InvalidKeyLen);
502 }
503
504 let (aes, tdes, block_len) = match self.algo {
505 Algorithm::CmacAes128 | Algorithm::CmacAes192 | Algorithm::CmacAes256 => {
506 (Some(Aes::new(key)), None, 16usize)
507 }
508 Algorithm::CmacTripleDes => (None, Some(TripleDes::new(key)), 8usize),
509 _ => unreachable!(),
510 };
511
512 let mut l = [0u8; 16];
514 if let Some(ref c) = aes {
515 c.encrypt_block(&mut l[..16]);
516 } else if let Some(ref c) = tdes {
517 c.encrypt_block(&mut l[..8]);
518 }
519 let k1 = cmac_double(&l[..block_len]);
520 let k2 = cmac_double(&k1[..block_len]);
521
522 let mut k1_arr = [0u8; 16];
523 let mut k2_arr = [0u8; 16];
524 k1_arr[..block_len].copy_from_slice(&k1[..block_len]);
525 k2_arr[..block_len].copy_from_slice(&k2[..block_len]);
526
527 Inner::Cmac {
528 aes,
529 tdes,
530 block_len,
531 k1: k1_arr,
532 k2: k2_arr,
533 x: [0u8; 16],
534 buf: [0u8; 16],
535 buf_len: 0,
536 }
537 }
538
539 Algorithm::Kmac128 | Algorithm::Kmac256 => {
541 let (rate, out_len) = match self.algo {
542 Algorithm::Kmac128 => (168usize, 32usize),
543 Algorithm::Kmac256 => (136usize, 64usize),
544 _ => unreachable!(),
545 };
546 let mut sponge = KeccakState::new(rate, 0x04);
548
549 let custom = custom.unwrap_or(&[]);
551 let mut prefix = Vec::new();
552 append_encode_string(&mut prefix, b"KMAC");
553 append_encode_string(&mut prefix, custom);
554 bytepad_to(&mut prefix, rate);
555 sponge.absorb(&prefix);
556
557 let mut keyenc = Vec::new();
559 append_encode_string(&mut keyenc, key);
560 bytepad_to(&mut keyenc, rate);
561 sponge.absorb(&keyenc);
562
563 Inner::Kmac { sponge, out_len }
564 }
565
566 Algorithm::GmacAes128 | Algorithm::GmacAes192 | Algorithm::GmacAes256 => {
568 let expected_key_len = match self.algo {
569 Algorithm::GmacAes128 => 16,
570 Algorithm::GmacAes192 => 24,
571 Algorithm::GmacAes256 => 32,
572 _ => unreachable!(),
573 };
574 if key.len() != expected_key_len {
575 return Err(Error::InvalidKeyLen);
576 }
577 let nonce = nonce.expect("init_with_nonce path");
578 debug_assert_eq!(nonce.len(), 12);
579
580 let aes = Aes::new(key);
581
582 let mut h = [0u8; 16];
584 aes.encrypt_block(&mut h);
585
586 let mut j0 = [0u8; 16];
588 j0[..12].copy_from_slice(nonce);
589 j0[15] = 1;
590 let mut e_j0 = j0;
591 aes.encrypt_block(&mut e_j0);
592
593 Inner::Gmac {
594 aes,
595 h,
596 e_j0,
597 y: [0u8; 16],
598 buf: [0u8; 16],
599 buf_len: 0,
600 total_len: 0,
601 }
602 }
603 };
604 self.initialized = true;
605 self.finalized = false;
606 Ok(())
607 }
608
609 pub const fn tag_len(&self) -> usize {
611 match self.algo {
612 Algorithm::HmacSha1 | Algorithm::HmacRipemd160 => 20,
613 Algorithm::HmacSha256 | Algorithm::HmacSha3_256 => 32,
614 Algorithm::HmacSha384 | Algorithm::HmacSha3_384 => 48,
615 Algorithm::HmacSha512 | Algorithm::HmacSha3_512 => 64,
616 Algorithm::CmacAes128 | Algorithm::CmacAes192 | Algorithm::CmacAes256 => 16,
617 Algorithm::CmacTripleDes => 8,
618 Algorithm::Kmac128 => 32,
619 Algorithm::Kmac256 => 64,
620 Algorithm::GmacAes128 | Algorithm::GmacAes192 | Algorithm::GmacAes256 => 16,
621 }
622 }
623
624 pub fn update(&mut self, data: &[u8]) -> Result<(), Error> {
627 if !self.initialized {
628 return Err(Error::NotInitialized);
629 }
630 if self.finalized {
631 return Err(Error::AlreadyFinalized);
632 }
633 match &mut self.inner {
634 Inner::None => unreachable!(),
635 Inner::Hmac { inner, .. } => {
636 inner.update(data);
637 }
638 Inner::Cmac {
639 aes,
640 tdes,
641 block_len,
642 buf,
643 buf_len,
644 x,
645 ..
646 } => {
647 let bs = *block_len;
648 let mut pos = 0;
649 while pos < data.len() {
650 let space = bs - *buf_len;
652 let take = space.min(data.len() - pos);
653 buf[*buf_len..*buf_len + take].copy_from_slice(&data[pos..pos + take]);
654 *buf_len += take;
655 pos += take;
656
657 if *buf_len == bs && pos < data.len() {
660 for i in 0..bs {
661 x[i] ^= buf[i];
662 }
663 if let Some(c) = aes.as_ref() {
664 c.encrypt_block(&mut x[..16]);
665 } else if let Some(c) = tdes.as_ref() {
666 c.encrypt_block(&mut x[..8]);
667 }
668 *buf_len = 0;
669 }
670 }
671 }
672 Inner::Kmac { sponge, .. } => {
673 sponge.absorb(data);
674 }
675 Inner::Gmac {
676 h,
677 y,
678 buf,
679 buf_len,
680 total_len,
681 ..
682 } => {
683 *total_len += data.len() as u64;
684 let mut pos = 0;
685 while pos < data.len() {
686 let space = 16 - *buf_len;
687 let take = space.min(data.len() - pos);
688 buf[*buf_len..*buf_len + take].copy_from_slice(&data[pos..pos + take]);
689 *buf_len += take;
690 pos += take;
691 if *buf_len == 16 {
692 for i in 0..16 {
693 y[i] ^= buf[i];
694 }
695 *y = gf128_mul(y, h);
696 *buf_len = 0;
697 }
698 }
699 }
700 }
701 Ok(())
702 }
703
704 pub fn sign(&mut self, out: &mut [u8]) -> Result<usize, Error> {
714 if !self.initialized {
715 return Err(Error::NotInitialized);
716 }
717 if self.finalized {
718 return Err(Error::AlreadyFinalized);
719 }
720 let tlen = self.tag_len();
721 if out.len() < tlen {
722 return Err(Error::OutputBufferTooSmall { needed: tlen });
723 }
724
725 let inner = core::mem::replace(&mut self.inner, Inner::None);
727
728 match inner {
729 Inner::None => unreachable!(),
730 Inner::Hmac { inner, opad_key } => {
731 let inner_digest = inner.finalize_inner();
732 let outer = match self.algo {
736 Algorithm::HmacSha1 => HmacState::Sha1(Sha1::new()),
737 Algorithm::HmacSha256 => HmacState::Sha256(Sha256::new()),
738 Algorithm::HmacSha384 => HmacState::Sha384(Sha384::new()),
739 Algorithm::HmacSha512 => HmacState::Sha512(Sha512::new()),
740 Algorithm::HmacSha3_256 => HmacState::Sha3_256(Sha3_256::new()),
741 Algorithm::HmacSha3_384 => HmacState::Sha3_384(Sha3_384::new()),
742 Algorithm::HmacSha3_512 => HmacState::Sha3_512(Sha3_512::new()),
743 Algorithm::HmacRipemd160 => HmacState::Ripemd160(Ripemd160::new()),
744 _ => unreachable!(),
745 };
746 let tag = outer.outer_hash(&opad_key, &inner_digest);
747 out[..tlen].copy_from_slice(&tag[..tlen]);
748 }
749 Inner::Cmac {
750 aes,
751 tdes,
752 block_len,
753 k1,
754 k2,
755 mut x,
756 mut buf,
757 buf_len,
758 } => {
759 let bs = block_len;
760 if buf_len == bs {
762 for i in 0..bs {
763 buf[i] ^= k1[i];
764 }
765 } else {
766 buf[buf_len] = 0x80;
767 for b in &mut buf[buf_len + 1..bs] {
768 *b = 0x00;
769 }
770 for i in 0..bs {
771 buf[i] ^= k2[i];
772 }
773 }
774 for i in 0..bs {
775 x[i] ^= buf[i];
776 }
777 if let Some(c) = aes.as_ref() {
778 c.encrypt_block(&mut x[..16]);
779 } else if let Some(c) = tdes.as_ref() {
780 c.encrypt_block(&mut x[..8]);
781 }
782 out[..tlen].copy_from_slice(&x[..tlen]);
783 }
784 Inner::Kmac { mut sponge, out_len } => {
785 let trailer = right_encode((out_len * 8) as u64);
787 sponge.absorb(&trailer);
788 sponge.squeeze(&mut out[..tlen]);
789 }
790 Inner::Gmac {
791 aes: _aes,
792 h,
793 e_j0,
794 mut y,
795 buf,
796 buf_len,
797 total_len,
798 } => {
799 if buf_len > 0 {
801 let mut last = [0u8; 16];
802 last[..buf_len].copy_from_slice(&buf[..buf_len]);
803 for i in 0..16 {
804 y[i] ^= last[i];
805 }
806 y = gf128_mul(&y, &h);
807 }
808 let mut len_block = [0u8; 16];
810 let a_bits = total_len * 8;
811 len_block[..8].copy_from_slice(&a_bits.to_be_bytes());
812 for i in 0..16 {
814 y[i] ^= len_block[i];
815 }
816 y = gf128_mul(&y, &h);
817 let mut tag = [0u8; 16];
819 for i in 0..16 {
820 tag[i] = y[i] ^ e_j0[i];
821 }
822 out[..tlen].copy_from_slice(&tag[..tlen]);
823 let _ = ghash_update;
825 }
826 }
827
828 self.finalized = true;
829 Ok(tlen)
830 }
831
832 pub fn verify(&mut self, expected_tag: &[u8]) -> Result<(), Error> {
843 let tlen = self.tag_len();
844 if expected_tag.is_empty() || expected_tag.len() > tlen {
845 let mut sink = vec![0u8; tlen];
847 let _ = self.sign(&mut sink);
848 return Err(Error::VerificationFailed);
849 }
850 let mut full = vec![0u8; tlen];
851 self.sign(&mut full)?;
852
853 let mut diff = 0u8;
855 for i in 0..expected_tag.len() {
856 diff |= full[i] ^ expected_tag[i];
857 }
858 if diff == 0 {
859 Ok(())
860 } else {
861 Err(Error::VerificationFailed)
862 }
863 }
864
865 pub fn sign_to_vec(&mut self) -> Result<Vec<u8>, Error> {
867 let tlen = self.tag_len();
868 let mut out = vec![0u8; tlen];
869 self.sign(&mut out)?;
870 Ok(out)
871 }
872}
873
874fn cmac_double(input: &[u8]) -> [u8; 16] {
882 let bs = input.len();
883 debug_assert!(bs == 8 || bs == 16);
884 let rb: u8 = if bs == 16 { 0x87 } else { 0x1B };
885 let mut out = [0u8; 16];
886 let mut carry: u8 = 0;
887 for i in (0..bs).rev() {
888 let v = input[i];
889 out[i] = (v << 1) | carry;
890 carry = (v >> 7) & 1;
891 }
892 if (input[0] & 0x80) != 0 {
893 out[bs - 1] ^= rb;
894 }
895 out
896}
897
898fn left_encode(x: u64) -> Vec<u8> {
905 let mut bytes = Vec::new();
906 let be = x.to_be_bytes();
907 let first = be.iter().position(|&b| b != 0).unwrap_or(7);
910 let n = (8 - first) as u8;
911 bytes.push(n);
912 bytes.extend_from_slice(&be[first..]);
913 bytes
914}
915
916fn right_encode(x: u64) -> Vec<u8> {
919 let mut bytes = Vec::new();
920 let be = x.to_be_bytes();
921 let first = be.iter().position(|&b| b != 0).unwrap_or(7);
922 let n = (8 - first) as u8;
923 bytes.extend_from_slice(&be[first..]);
924 bytes.push(n);
925 bytes
926}
927
928fn append_encode_string(out: &mut Vec<u8>, s: &[u8]) {
930 out.extend_from_slice(&left_encode((s.len() as u64) * 8));
931 out.extend_from_slice(s);
932}
933
934fn bytepad_to(buf: &mut Vec<u8>, w: usize) {
937 let prefix = left_encode(w as u64);
941 let mut full = Vec::with_capacity(prefix.len() + buf.len());
942 full.extend_from_slice(&prefix);
943 full.extend_from_slice(buf);
944 let pad = (w - (full.len() % w)) % w;
945 full.extend(std::iter::repeat_n(0u8, pad));
946 *buf = full;
947}
948
949#[cfg(test)]
954mod tests {
955 use super::*;
956
957 fn hex(s: &str) -> Vec<u8> {
958 let s: String = s.chars().filter(|c| !c.is_whitespace()).collect();
959 (0..s.len())
960 .step_by(2)
961 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
962 .collect()
963 }
964
965 #[test]
968 fn hmac_sha256_rfc4231_tc1() {
969 let key = hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
970 let data = b"Hi There";
971 let expected = hex("b0344c61d8db38535ca8afceaf0bf12b\
972 881dc200c9833da726e9376c2e32cff7");
973
974 let mut m = Mac::new(Algorithm::HmacSha256);
975 m.init(&key).unwrap();
976 m.update(data).unwrap();
977 let tag = m.sign_to_vec().unwrap();
978 assert_eq!(tag, expected);
979 }
980
981 #[test]
982 fn hmac_sha256_rfc4231_tc2_streaming() {
983 let key = b"Jefe";
985 let expected = hex("5bdcc146bf60754e6a042426089575c7\
986 5a003f089d2739839dec58b964ec3843");
987 let data = b"what do ya want for nothing?";
988
989 let mut m = Mac::new(Algorithm::HmacSha256);
990 m.init(key).unwrap();
991 for chunk in data.chunks(3) {
992 m.update(chunk).unwrap();
993 }
994 let tag = m.sign_to_vec().unwrap();
995 assert_eq!(tag, expected);
996 }
997
998 #[test]
999 fn hmac_sha256_long_key_rfc4231_tc6() {
1000 let key = vec![0xaau8; 131];
1002 let data = b"Test Using Larger Than Block-Size Key - Hash Key First";
1003 let expected = hex("60e431591ee0b67f0d8a26aacbf5b77f\
1004 8e0bc6213728c5140546040f0ee37f54");
1005
1006 let mut m = Mac::new(Algorithm::HmacSha256);
1007 m.init(&key).unwrap();
1008 m.update(data).unwrap();
1009 let tag = m.sign_to_vec().unwrap();
1010 assert_eq!(tag, expected);
1011 }
1012
1013 #[test]
1014 fn hmac_sha512_rfc4231_tc1() {
1015 let key = hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
1016 let data = b"Hi There";
1017 let expected = hex("87aa7cdea5ef619d4ff0b4241a1d6cb0\
1018 2379f4e2ce4ec2787ad0b30545e17cde\
1019 daa833b7d6b8a702038b274eaea3f4e4\
1020 be9d914eeb61f1702e696c203a126854");
1021
1022 let mut m = Mac::new(Algorithm::HmacSha512);
1023 m.init(&key).unwrap();
1024 m.update(data).unwrap();
1025 assert_eq!(m.sign_to_vec().unwrap(), expected);
1026 }
1027
1028 #[test]
1029 fn hmac_sha1_rfc2202_tc1() {
1030 let key = hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
1032 let data = b"Hi There";
1033 let expected = hex("b617318655057264e28bc0b6fb378c8ef146be00");
1034
1035 let mut m = Mac::new(Algorithm::HmacSha1);
1036 m.init(&key).unwrap();
1037 m.update(data).unwrap();
1038 assert_eq!(m.sign_to_vec().unwrap(), expected);
1039 }
1040
1041 #[test]
1045 fn cmac_aes128_rfc4493_empty() {
1046 let key = hex("2b7e151628aed2a6abf7158809cf4f3c");
1047 let expected = hex("bb1d6929e95937287fa37d129b756746");
1048
1049 let mut m = Mac::new(Algorithm::CmacAes128);
1050 m.init(&key).unwrap();
1051 m.update(b"").unwrap();
1052 assert_eq!(m.sign_to_vec().unwrap(), expected);
1053 }
1054
1055 #[test]
1057 fn cmac_aes128_rfc4493_one_block() {
1058 let key = hex("2b7e151628aed2a6abf7158809cf4f3c");
1059 let m_bytes = hex("6bc1bee22e409f96e93d7e117393172a");
1060 let expected = hex("070a16b46b4d4144f79bdd9dd04a287c");
1061
1062 let mut m = Mac::new(Algorithm::CmacAes128);
1063 m.init(&key).unwrap();
1064 m.update(&m_bytes).unwrap();
1065 assert_eq!(m.sign_to_vec().unwrap(), expected);
1066 }
1067
1068 #[test]
1070 fn cmac_aes128_rfc4493_40bytes() {
1071 let key = hex("2b7e151628aed2a6abf7158809cf4f3c");
1072 let m_bytes = hex("6bc1bee22e409f96e93d7e117393172a\
1073 ae2d8a571e03ac9c9eb76fac45af8e51\
1074 30c81c46a35ce411");
1075 let expected = hex("dfa66747de9ae63030ca32611497c827");
1076
1077 let mut m = Mac::new(Algorithm::CmacAes128);
1078 m.init(&key).unwrap();
1079 m.update(&m_bytes[..7]).unwrap();
1081 m.update(&m_bytes[7..23]).unwrap();
1082 m.update(&m_bytes[23..]).unwrap();
1083 assert_eq!(m.sign_to_vec().unwrap(), expected);
1084 }
1085
1086 #[test]
1088 fn cmac_aes128_rfc4493_64bytes() {
1089 let key = hex("2b7e151628aed2a6abf7158809cf4f3c");
1090 let m_bytes = hex("6bc1bee22e409f96e93d7e117393172a\
1091 ae2d8a571e03ac9c9eb76fac45af8e51\
1092 30c81c46a35ce411e5fbc1191a0a52ef\
1093 f69f2445df4f9b17ad2b417be66c3710");
1094 let expected = hex("51f0bebf7e3b9d92fc49741779363cfe");
1095
1096 let mut m = Mac::new(Algorithm::CmacAes128);
1097 m.init(&key).unwrap();
1098 m.update(&m_bytes).unwrap();
1099 assert_eq!(m.sign_to_vec().unwrap(), expected);
1100 }
1101
1102 #[test]
1107 fn kmac128_sample1() {
1108 let key = hex("404142434445464748494a4b4c4d4e4f\
1110 505152535455565758595a5b5c5d5e5f");
1111 let data = hex("00010203");
1112 let expected = hex("e5780b0d3ea6f7d3a429c5706aa43a00\
1113 fadbd7d49628839e3187243f456ee14e");
1114
1115 let mut m = Mac::new(Algorithm::Kmac128);
1116 m.init(&key).unwrap();
1117 m.update(&data).unwrap();
1118 assert_eq!(m.sign_to_vec().unwrap(), expected);
1119 }
1120
1121 #[test]
1122 fn kmac128_sample2_with_custom() {
1123 let key = hex("404142434445464748494a4b4c4d4e4f\
1125 505152535455565758595a5b5c5d5e5f");
1126 let data = hex("00010203");
1127 let custom = b"My Tagged Application";
1128 let expected = hex("3b1fba963cd8b0b59e8c1a6d71888b71\
1129 43651af8ba0a7070c0979e2811324aa5");
1130
1131 let mut m = Mac::new(Algorithm::Kmac128);
1132 m.init_kmac(&key, custom).unwrap();
1133 m.update(&data).unwrap();
1134 assert_eq!(m.sign_to_vec().unwrap(), expected);
1135 }
1136
1137 #[test]
1138 fn kmac256_sample4_with_custom() {
1139 let key = hex("404142434445464748494a4b4c4d4e4f\
1142 505152535455565758595a5b5c5d5e5f");
1143 let data = hex("00010203");
1144 let custom = b"My Tagged Application";
1145 let expected = hex("20c570c31346f703c9ac36c61c03cb64\
1146 c3970d0cfc787e9b79599d273a68d2f7\
1147 f69d4cc3de9d104a351689f27cf6f595\
1148 1f0103f33f4f24871024d9c27773a8dd");
1149
1150 let mut m = Mac::new(Algorithm::Kmac256);
1151 m.init_kmac(&key, custom).unwrap();
1152 m.update(&data).unwrap();
1153 assert_eq!(m.sign_to_vec().unwrap(), expected);
1154 }
1155
1156 #[test]
1161 fn gmac_aes128_matches_gcm_empty_plaintext() {
1162 use crate::cipher::aes::Aes128;
1163 use crate::cipher::modes::Gcm;
1164 let key = hex("feffe9928665731c6d6a8f9467308308");
1165 let nonce_bytes = hex("cafebabefacedbaddecaf888");
1166 let nonce: [u8; 12] = nonce_bytes.clone().try_into().unwrap();
1167 let aad = hex("d9313225f88406e5a55909c5aff5269a\
1168 86a7a9531534f7da2e4c303d8a318a72\
1169 1c3c0c95956809532fcf0e2449a6b525");
1170
1171 let cipher = Aes128::new(&key);
1172 let (_ct, tag_ref) = Gcm::encrypt(&cipher, &nonce, &aad, &[]);
1173
1174 let mut m = Mac::new(Algorithm::GmacAes128);
1175 m.init_with_nonce(&key, &nonce_bytes).unwrap();
1176 for chunk in aad.chunks(7) {
1178 m.update(chunk).unwrap();
1179 }
1180 let tag = m.sign_to_vec().unwrap();
1181 assert_eq!(tag.len(), 16);
1182 assert_eq!(tag, tag_ref.to_vec());
1183 }
1184
1185 #[test]
1186 fn gmac_verify_truncated() {
1187 let key = hex("feffe9928665731c6d6a8f9467308308");
1188 let nonce = hex("cafebabefacedbaddecaf888");
1189 let aad = b"some authenticated data";
1190
1191 let mut signer = Mac::new(Algorithm::GmacAes128);
1192 signer.init_with_nonce(&key, &nonce).unwrap();
1193 signer.update(aad).unwrap();
1194 let full_tag = signer.sign_to_vec().unwrap();
1195
1196 let truncated = &full_tag[..12];
1198 let mut verifier = Mac::new(Algorithm::GmacAes128);
1199 verifier.init_with_nonce(&key, &nonce).unwrap();
1200 verifier.update(aad).unwrap();
1201 assert_eq!(verifier.verify(truncated), Ok(()));
1202
1203 let mut bad = full_tag.clone();
1205 bad[0] ^= 0xFF;
1206 let mut verifier = Mac::new(Algorithm::GmacAes128);
1207 verifier.init_with_nonce(&key, &nonce).unwrap();
1208 verifier.update(aad).unwrap();
1209 assert_eq!(verifier.verify(&bad[..12]), Err(Error::VerificationFailed));
1210 }
1211
1212 #[test]
1215 fn round_trip_all_hmac_and_cmac() {
1216 let key128 = [0x42u8; 16];
1217 let key192 = [0x42u8; 24];
1218 let key256 = [0x42u8; 32];
1219
1220 let cases: &[(Algorithm, &[u8])] = &[
1221 (Algorithm::HmacSha1, b"hmac-sha1-key-here"),
1222 (Algorithm::HmacSha256, b"hmac-sha256-key-here"),
1223 (Algorithm::HmacSha384, b"hmac-sha384-key-here"),
1224 (Algorithm::HmacSha512, b"hmac-sha512-key-here"),
1225 (Algorithm::HmacSha3_256, b"hmac-sha3-256-key"),
1226 (Algorithm::HmacSha3_384, b"hmac-sha3-384-key"),
1227 (Algorithm::HmacSha3_512, b"hmac-sha3-512-key"),
1228 (Algorithm::HmacRipemd160, b"hmac-ripemd160-key"),
1229 (Algorithm::CmacAes128, &key128),
1230 (Algorithm::CmacAes192, &key192),
1231 (Algorithm::CmacAes256, &key256),
1232 (Algorithm::CmacTripleDes, &key192),
1233 ];
1234
1235 for (algo, key) in cases {
1236 let mut signer = Mac::new(*algo);
1237 signer.init(key).unwrap();
1238 signer.update(b"the quick brown fox jumps over the lazy dog").unwrap();
1239 let tag = signer.sign_to_vec().unwrap();
1240
1241 let mut verifier = Mac::new(*algo);
1242 verifier.init(key).unwrap();
1243 verifier.update(b"the quick brown fox jumps over the lazy dog").unwrap();
1244 assert_eq!(verifier.verify(&tag), Ok(()), "{:?}", algo);
1245
1246 let mut bad = tag.clone();
1248 bad[0] ^= 0x01;
1249 let mut verifier = Mac::new(*algo);
1250 verifier.init(key).unwrap();
1251 verifier.update(b"the quick brown fox jumps over the lazy dog").unwrap();
1252 assert_eq!(verifier.verify(&bad), Err(Error::VerificationFailed), "{:?}", algo);
1253 }
1254 }
1255
1256 #[test]
1259 fn hmac_init_after_use_resets() {
1260 let mut m = Mac::new(Algorithm::HmacSha256);
1261 m.init(b"first key").unwrap();
1262 m.update(b"first message").unwrap();
1263 let _ = m.sign_to_vec().unwrap();
1264
1265 m.init(b"second key").unwrap();
1267 m.update(b"second message").unwrap();
1268 let tag = m.sign_to_vec().unwrap();
1269
1270 let mut ref_m = Mac::new(Algorithm::HmacSha256);
1272 ref_m.init(b"second key").unwrap();
1273 ref_m.update(b"second message").unwrap();
1274 assert_eq!(tag, ref_m.sign_to_vec().unwrap());
1275 }
1276
1277 #[test]
1278 fn wrong_init_variant_rejected() {
1279 let mut m = Mac::new(Algorithm::GmacAes128);
1280 assert_eq!(m.init(&[0u8; 16]), Err(Error::WrongInitVariant));
1281
1282 let mut m = Mac::new(Algorithm::HmacSha256);
1283 assert_eq!(m.init_with_nonce(b"k", &[0u8; 12]), Err(Error::WrongInitVariant));
1284
1285 let mut m = Mac::new(Algorithm::HmacSha256);
1286 assert_eq!(m.init_kmac(b"k", b""), Err(Error::WrongInitVariant));
1287 }
1288
1289 #[test]
1290 fn cmac_invalid_key_len() {
1291 let mut m = Mac::new(Algorithm::CmacAes128);
1292 assert_eq!(m.init(&[0u8; 17]), Err(Error::InvalidKeyLen));
1293 }
1294
1295 #[test]
1296 fn gmac_invalid_nonce_len() {
1297 let mut m = Mac::new(Algorithm::GmacAes128);
1298 assert_eq!(m.init_with_nonce(&[0u8; 16], &[0u8; 11]), Err(Error::InvalidNonceLen));
1299 }
1300
1301 #[test]
1302 fn output_too_small() {
1303 let mut m = Mac::new(Algorithm::HmacSha256);
1304 m.init(b"k").unwrap();
1305 m.update(b"data").unwrap();
1306 let mut small = [0u8; 8];
1307 assert!(matches!(m.sign(&mut small), Err(Error::OutputBufferTooSmall { .. })));
1308 }
1309
1310 #[test]
1311 fn verify_rejects_empty_or_too_long() {
1312 let mut m = Mac::new(Algorithm::HmacSha256);
1313 m.init(b"k").unwrap();
1314 m.update(b"d").unwrap();
1315 assert_eq!(m.verify(&[]), Err(Error::VerificationFailed));
1316
1317 let mut m = Mac::new(Algorithm::HmacSha256);
1318 m.init(b"k").unwrap();
1319 m.update(b"d").unwrap();
1320 assert_eq!(m.verify(&[0u8; 33]), Err(Error::VerificationFailed));
1321 }
1322}