1use crate::cipher::aes::Aes;
77use crate::cipher::des::TripleDes;
78use crate::cipher::modes::{gf128_mul, ghash_update};
79use crate::hash::ripemd160::Ripemd160;
80use crate::hash::sha1::Sha1;
81use crate::hash::sha3::{KeccakState, Sha3_256, Sha3_384, Sha3_512};
82use crate::hash::sha256::Sha256;
83use crate::hash::sha384::Sha384;
84use crate::hash::sha512::Sha512;
85use crate::{BlockCipher, Hasher};
86
87#[derive(Clone, Copy, Debug, PartialEq, Eq)]
93pub enum Algorithm {
94 HmacSha1,
96 HmacSha256,
98 HmacSha384,
100 HmacSha512,
102 HmacSha3_256,
104 HmacSha3_384,
106 HmacSha3_512,
108 HmacRipemd160,
110
111 CmacAes128,
113 CmacAes192,
115 CmacAes256,
117 CmacTripleDes,
119
120 Kmac128,
122 Kmac256,
124
125 GmacAes128,
128 GmacAes192,
130 GmacAes256,
132}
133
134#[derive(Clone, Copy, Debug, PartialEq, Eq)]
136pub enum Error {
137 InvalidKeyLen,
139 InvalidNonceLen,
141 NotInitialized,
143 AlreadyFinalized,
146 OutputBufferTooSmall {
149 needed: usize,
151 },
152 WrongInitVariant,
155 VerificationFailed,
157}
158
159enum HmacState {
164 Sha1(Sha1),
165 Sha256(Sha256),
166 Sha384(Sha384),
167 Sha512(Sha512),
168 Sha3_256(Sha3_256),
169 Sha3_384(Sha3_384),
170 Sha3_512(Sha3_512),
171 Ripemd160(Ripemd160),
172}
173
174impl HmacState {
175 fn block_len(&self) -> usize {
176 match self {
177 HmacState::Sha1(_) => Sha1::BLOCK_LEN,
178 HmacState::Sha256(_) => Sha256::BLOCK_LEN,
179 HmacState::Sha384(_) => Sha384::BLOCK_LEN,
180 HmacState::Sha512(_) => Sha512::BLOCK_LEN,
181 HmacState::Sha3_256(_) => Sha3_256::BLOCK_LEN,
182 HmacState::Sha3_384(_) => Sha3_384::BLOCK_LEN,
183 HmacState::Sha3_512(_) => Sha3_512::BLOCK_LEN,
184 HmacState::Ripemd160(_) => Ripemd160::BLOCK_LEN,
185 }
186 }
187
188 fn output_len(&self) -> usize {
189 match self {
190 HmacState::Sha1(_) => Sha1::OUTPUT_LEN,
191 HmacState::Sha256(_) => Sha256::OUTPUT_LEN,
192 HmacState::Sha384(_) => Sha384::OUTPUT_LEN,
193 HmacState::Sha512(_) => Sha512::OUTPUT_LEN,
194 HmacState::Sha3_256(_) => Sha3_256::OUTPUT_LEN,
195 HmacState::Sha3_384(_) => Sha3_384::OUTPUT_LEN,
196 HmacState::Sha3_512(_) => Sha3_512::OUTPUT_LEN,
197 HmacState::Ripemd160(_) => Ripemd160::OUTPUT_LEN,
198 }
199 }
200
201 fn update(&mut self, data: &[u8]) {
202 match self {
203 HmacState::Sha1(h) => h.update(data),
204 HmacState::Sha256(h) => h.update(data),
205 HmacState::Sha384(h) => h.update(data),
206 HmacState::Sha512(h) => h.update(data),
207 HmacState::Sha3_256(h) => h.update(data),
208 HmacState::Sha3_384(h) => h.update(data),
209 HmacState::Sha3_512(h) => h.update(data),
210 HmacState::Ripemd160(h) => h.update(data),
211 }
212 }
213
214 fn hash_key(&self, key: &[u8]) -> Vec<u8> {
217 match self {
218 HmacState::Sha1(_) => Sha1::hash(key),
219 HmacState::Sha256(_) => Sha256::hash(key),
220 HmacState::Sha384(_) => Sha384::hash(key),
221 HmacState::Sha512(_) => Sha512::hash(key),
222 HmacState::Sha3_256(_) => Sha3_256::hash(key),
223 HmacState::Sha3_384(_) => Sha3_384::hash(key),
224 HmacState::Sha3_512(_) => Sha3_512::hash(key),
225 HmacState::Ripemd160(_) => Ripemd160::hash(key),
226 }
227 }
228
229 fn finalize_inner(self) -> Vec<u8> {
231 match self {
232 HmacState::Sha1(h) => h.finalize(),
233 HmacState::Sha256(h) => h.finalize(),
234 HmacState::Sha384(h) => h.finalize(),
235 HmacState::Sha512(h) => h.finalize(),
236 HmacState::Sha3_256(h) => h.finalize(),
237 HmacState::Sha3_384(h) => h.finalize(),
238 HmacState::Sha3_512(h) => h.finalize(),
239 HmacState::Ripemd160(h) => h.finalize(),
240 }
241 }
242
243 fn outer_hash(&self, opad_key: &[u8], inner_digest: &[u8]) -> Vec<u8> {
246 match self {
247 HmacState::Sha1(_) => {
248 let mut h = Sha1::new();
249 h.update(opad_key);
250 h.update(inner_digest);
251 h.finalize()
252 }
253 HmacState::Sha256(_) => {
254 let mut h = Sha256::new();
255 h.update(opad_key);
256 h.update(inner_digest);
257 h.finalize()
258 }
259 HmacState::Sha384(_) => {
260 let mut h = Sha384::new();
261 h.update(opad_key);
262 h.update(inner_digest);
263 h.finalize()
264 }
265 HmacState::Sha512(_) => {
266 let mut h = Sha512::new();
267 h.update(opad_key);
268 h.update(inner_digest);
269 h.finalize()
270 }
271 HmacState::Sha3_256(_) => {
272 let mut h = Sha3_256::new();
273 h.update(opad_key);
274 h.update(inner_digest);
275 h.finalize()
276 }
277 HmacState::Sha3_384(_) => {
278 let mut h = Sha3_384::new();
279 h.update(opad_key);
280 h.update(inner_digest);
281 h.finalize()
282 }
283 HmacState::Sha3_512(_) => {
284 let mut h = Sha3_512::new();
285 h.update(opad_key);
286 h.update(inner_digest);
287 h.finalize()
288 }
289 HmacState::Ripemd160(_) => {
290 let mut h = Ripemd160::new();
291 h.update(opad_key);
292 h.update(inner_digest);
293 h.finalize()
294 }
295 }
296 }
297}
298
299enum Inner {
301 None,
302 Hmac {
303 inner: HmacState,
305 opad_key: Vec<u8>,
307 },
308 Cmac {
309 aes: Option<Aes>,
311 tdes: Option<TripleDes>,
313 block_len: usize,
314 k1: [u8; 16],
316 k2: [u8; 16],
318 x: [u8; 16],
320 buf: [u8; 16],
323 buf_len: usize,
324 },
325 Kmac {
326 sponge: KeccakState,
329 out_len: usize,
331 },
332 Gmac {
333 aes: Aes,
335 h: [u8; 16],
337 e_j0: [u8; 16],
340 y: [u8; 16],
342 buf: [u8; 16],
344 buf_len: usize,
345 total_len: u64,
348 },
349}
350
351pub struct Mac {
360 algo: Algorithm,
361 inner: Inner,
362 initialized: bool,
363 finalized: bool,
364}
365
366impl Mac {
367 pub fn new(algo: Algorithm) -> Self {
372 Self {
373 algo,
374 inner: Inner::None,
375 initialized: false,
376 finalized: false,
377 }
378 }
379
380 pub fn init(&mut self, key: &[u8]) -> Result<(), Error> {
394 match self.algo {
395 Algorithm::GmacAes128 | Algorithm::GmacAes192 | Algorithm::GmacAes256 => Err(Error::WrongInitVariant),
396 Algorithm::Kmac128 | Algorithm::Kmac256 => self.init_kmac(key, &[]),
397 _ => self.init_internal(key, None, None),
398 }
399 }
400
401 pub fn init_kmac(&mut self, key: &[u8], custom: &[u8]) -> Result<(), Error> {
407 match self.algo {
408 Algorithm::Kmac128 | Algorithm::Kmac256 => self.init_internal(key, None, Some(custom)),
409 _ => Err(Error::WrongInitVariant),
410 }
411 }
412
413 pub fn init_with_nonce(&mut self, key: &[u8], nonce: &[u8]) -> Result<(), Error> {
423 match self.algo {
424 Algorithm::GmacAes128 | Algorithm::GmacAes192 | Algorithm::GmacAes256 => {
425 if nonce.len() != 12 {
426 return Err(Error::InvalidNonceLen);
427 }
428 self.init_internal(key, Some(nonce), None)
429 }
430 _ => Err(Error::WrongInitVariant),
431 }
432 }
433
434 fn init_internal(&mut self, key: &[u8], nonce: Option<&[u8]>, custom: Option<&[u8]>) -> Result<(), Error> {
435 self.inner = match self.algo {
436 Algorithm::HmacSha1
438 | Algorithm::HmacSha256
439 | Algorithm::HmacSha384
440 | Algorithm::HmacSha512
441 | Algorithm::HmacSha3_256
442 | Algorithm::HmacSha3_384
443 | Algorithm::HmacSha3_512
444 | Algorithm::HmacRipemd160 => {
445 let mut state = match self.algo {
446 Algorithm::HmacSha1 => HmacState::Sha1(Sha1::new()),
447 Algorithm::HmacSha256 => HmacState::Sha256(Sha256::new()),
448 Algorithm::HmacSha384 => HmacState::Sha384(Sha384::new()),
449 Algorithm::HmacSha512 => HmacState::Sha512(Sha512::new()),
450 Algorithm::HmacSha3_256 => HmacState::Sha3_256(Sha3_256::new()),
451 Algorithm::HmacSha3_384 => HmacState::Sha3_384(Sha3_384::new()),
452 Algorithm::HmacSha3_512 => HmacState::Sha3_512(Sha3_512::new()),
453 Algorithm::HmacRipemd160 => HmacState::Ripemd160(Ripemd160::new()),
454 _ => unreachable!(),
455 };
456 let block_len = state.block_len();
457
458 let mut key_block = vec![0u8; block_len];
460 if key.len() > block_len {
461 let hashed = state.hash_key(key);
462 key_block[..hashed.len()].copy_from_slice(&hashed);
463 } else {
464 key_block[..key.len()].copy_from_slice(key);
465 }
466
467 let mut ipad_key = key_block.clone();
469 let mut opad_key = key_block;
470 for b in &mut ipad_key {
471 *b ^= 0x36;
472 }
473 for b in &mut opad_key {
474 *b ^= 0x5C;
475 }
476
477 state.update(&ipad_key);
478 Inner::Hmac { inner: state, opad_key }
479 }
480
481 Algorithm::CmacAes128 | Algorithm::CmacAes192 | Algorithm::CmacAes256 | Algorithm::CmacTripleDes => {
483 let expected_key_len = match self.algo {
484 Algorithm::CmacAes128 => 16,
485 Algorithm::CmacAes192 => 24,
486 Algorithm::CmacAes256 => 32,
487 Algorithm::CmacTripleDes => 24,
488 _ => unreachable!(),
489 };
490 if key.len() != expected_key_len {
491 return Err(Error::InvalidKeyLen);
492 }
493
494 let (aes, tdes, block_len) = match self.algo {
495 Algorithm::CmacAes128 | Algorithm::CmacAes192 | Algorithm::CmacAes256 => {
496 (Some(Aes::new(key)), None, 16usize)
497 }
498 Algorithm::CmacTripleDes => (None, Some(TripleDes::new(key)), 8usize),
499 _ => unreachable!(),
500 };
501
502 let mut l = [0u8; 16];
504 if let Some(ref c) = aes {
505 c.encrypt_block(&mut l[..16]);
506 } else if let Some(ref c) = tdes {
507 c.encrypt_block(&mut l[..8]);
508 }
509 let k1 = cmac_double(&l[..block_len]);
510 let k2 = cmac_double(&k1[..block_len]);
511
512 let mut k1_arr = [0u8; 16];
513 let mut k2_arr = [0u8; 16];
514 k1_arr[..block_len].copy_from_slice(&k1[..block_len]);
515 k2_arr[..block_len].copy_from_slice(&k2[..block_len]);
516
517 Inner::Cmac {
518 aes,
519 tdes,
520 block_len,
521 k1: k1_arr,
522 k2: k2_arr,
523 x: [0u8; 16],
524 buf: [0u8; 16],
525 buf_len: 0,
526 }
527 }
528
529 Algorithm::Kmac128 | Algorithm::Kmac256 => {
531 let (rate, out_len) = match self.algo {
532 Algorithm::Kmac128 => (168usize, 32usize),
533 Algorithm::Kmac256 => (136usize, 64usize),
534 _ => unreachable!(),
535 };
536 let mut sponge = KeccakState::new(rate, 0x04);
538
539 let custom = custom.unwrap_or(&[]);
541 let mut prefix = Vec::new();
542 append_encode_string(&mut prefix, b"KMAC");
543 append_encode_string(&mut prefix, custom);
544 bytepad_to(&mut prefix, rate);
545 sponge.absorb(&prefix);
546
547 let mut keyenc = Vec::new();
549 append_encode_string(&mut keyenc, key);
550 bytepad_to(&mut keyenc, rate);
551 sponge.absorb(&keyenc);
552
553 Inner::Kmac { sponge, out_len }
554 }
555
556 Algorithm::GmacAes128 | Algorithm::GmacAes192 | Algorithm::GmacAes256 => {
558 let expected_key_len = match self.algo {
559 Algorithm::GmacAes128 => 16,
560 Algorithm::GmacAes192 => 24,
561 Algorithm::GmacAes256 => 32,
562 _ => unreachable!(),
563 };
564 if key.len() != expected_key_len {
565 return Err(Error::InvalidKeyLen);
566 }
567 let nonce = nonce.expect("init_with_nonce path");
568 debug_assert_eq!(nonce.len(), 12);
569
570 let aes = Aes::new(key);
571
572 let mut h = [0u8; 16];
574 aes.encrypt_block(&mut h);
575
576 let mut j0 = [0u8; 16];
578 j0[..12].copy_from_slice(nonce);
579 j0[15] = 1;
580 let mut e_j0 = j0;
581 aes.encrypt_block(&mut e_j0);
582
583 Inner::Gmac {
584 aes,
585 h,
586 e_j0,
587 y: [0u8; 16],
588 buf: [0u8; 16],
589 buf_len: 0,
590 total_len: 0,
591 }
592 }
593 };
594 self.initialized = true;
595 self.finalized = false;
596 Ok(())
597 }
598
599 pub const fn tag_len(&self) -> usize {
601 match self.algo {
602 Algorithm::HmacSha1 | Algorithm::HmacRipemd160 => 20,
603 Algorithm::HmacSha256 | Algorithm::HmacSha3_256 => 32,
604 Algorithm::HmacSha384 | Algorithm::HmacSha3_384 => 48,
605 Algorithm::HmacSha512 | Algorithm::HmacSha3_512 => 64,
606 Algorithm::CmacAes128 | Algorithm::CmacAes192 | Algorithm::CmacAes256 => 16,
607 Algorithm::CmacTripleDes => 8,
608 Algorithm::Kmac128 => 32,
609 Algorithm::Kmac256 => 64,
610 Algorithm::GmacAes128 | Algorithm::GmacAes192 | Algorithm::GmacAes256 => 16,
611 }
612 }
613
614 pub fn update(&mut self, data: &[u8]) -> Result<(), Error> {
617 if !self.initialized {
618 return Err(Error::NotInitialized);
619 }
620 if self.finalized {
621 return Err(Error::AlreadyFinalized);
622 }
623 match &mut self.inner {
624 Inner::None => unreachable!(),
625 Inner::Hmac { inner, .. } => {
626 inner.update(data);
627 }
628 Inner::Cmac {
629 aes,
630 tdes,
631 block_len,
632 buf,
633 buf_len,
634 x,
635 ..
636 } => {
637 let bs = *block_len;
638 let mut pos = 0;
639 while pos < data.len() {
640 let space = bs - *buf_len;
642 let take = space.min(data.len() - pos);
643 buf[*buf_len..*buf_len + take].copy_from_slice(&data[pos..pos + take]);
644 *buf_len += take;
645 pos += take;
646
647 if *buf_len == bs && pos < data.len() {
650 for i in 0..bs {
651 x[i] ^= buf[i];
652 }
653 if let Some(c) = aes.as_ref() {
654 c.encrypt_block(&mut x[..16]);
655 } else if let Some(c) = tdes.as_ref() {
656 c.encrypt_block(&mut x[..8]);
657 }
658 *buf_len = 0;
659 }
660 }
661 }
662 Inner::Kmac { sponge, .. } => {
663 sponge.absorb(data);
664 }
665 Inner::Gmac {
666 h,
667 y,
668 buf,
669 buf_len,
670 total_len,
671 ..
672 } => {
673 *total_len += data.len() as u64;
674 let mut pos = 0;
675 while pos < data.len() {
676 let space = 16 - *buf_len;
677 let take = space.min(data.len() - pos);
678 buf[*buf_len..*buf_len + take].copy_from_slice(&data[pos..pos + take]);
679 *buf_len += take;
680 pos += take;
681 if *buf_len == 16 {
682 for i in 0..16 {
683 y[i] ^= buf[i];
684 }
685 *y = gf128_mul(y, h);
686 *buf_len = 0;
687 }
688 }
689 }
690 }
691 Ok(())
692 }
693
694 pub fn sign(&mut self, out: &mut [u8]) -> Result<usize, Error> {
704 if !self.initialized {
705 return Err(Error::NotInitialized);
706 }
707 if self.finalized {
708 return Err(Error::AlreadyFinalized);
709 }
710 let tlen = self.tag_len();
711 if out.len() < tlen {
712 return Err(Error::OutputBufferTooSmall { needed: tlen });
713 }
714
715 let inner = core::mem::replace(&mut self.inner, Inner::None);
717
718 match inner {
719 Inner::None => unreachable!(),
720 Inner::Hmac { inner, opad_key } => {
721 let inner_digest = inner.finalize_inner();
722 let outer = match self.algo {
726 Algorithm::HmacSha1 => HmacState::Sha1(Sha1::new()),
727 Algorithm::HmacSha256 => HmacState::Sha256(Sha256::new()),
728 Algorithm::HmacSha384 => HmacState::Sha384(Sha384::new()),
729 Algorithm::HmacSha512 => HmacState::Sha512(Sha512::new()),
730 Algorithm::HmacSha3_256 => HmacState::Sha3_256(Sha3_256::new()),
731 Algorithm::HmacSha3_384 => HmacState::Sha3_384(Sha3_384::new()),
732 Algorithm::HmacSha3_512 => HmacState::Sha3_512(Sha3_512::new()),
733 Algorithm::HmacRipemd160 => HmacState::Ripemd160(Ripemd160::new()),
734 _ => unreachable!(),
735 };
736 let tag = outer.outer_hash(&opad_key, &inner_digest);
737 out[..tlen].copy_from_slice(&tag[..tlen]);
738 }
739 Inner::Cmac {
740 aes,
741 tdes,
742 block_len,
743 k1,
744 k2,
745 mut x,
746 mut buf,
747 buf_len,
748 } => {
749 let bs = block_len;
750 if buf_len == bs {
752 for i in 0..bs {
753 buf[i] ^= k1[i];
754 }
755 } else {
756 buf[buf_len] = 0x80;
757 for b in &mut buf[buf_len + 1..bs] {
758 *b = 0x00;
759 }
760 for i in 0..bs {
761 buf[i] ^= k2[i];
762 }
763 }
764 for i in 0..bs {
765 x[i] ^= buf[i];
766 }
767 if let Some(c) = aes.as_ref() {
768 c.encrypt_block(&mut x[..16]);
769 } else if let Some(c) = tdes.as_ref() {
770 c.encrypt_block(&mut x[..8]);
771 }
772 out[..tlen].copy_from_slice(&x[..tlen]);
773 }
774 Inner::Kmac { mut sponge, out_len } => {
775 let trailer = right_encode((out_len * 8) as u64);
777 sponge.absorb(&trailer);
778 sponge.squeeze(&mut out[..tlen]);
779 }
780 Inner::Gmac {
781 aes: _aes,
782 h,
783 e_j0,
784 mut y,
785 buf,
786 buf_len,
787 total_len,
788 } => {
789 if buf_len > 0 {
791 let mut last = [0u8; 16];
792 last[..buf_len].copy_from_slice(&buf[..buf_len]);
793 for i in 0..16 {
794 y[i] ^= last[i];
795 }
796 y = gf128_mul(&y, &h);
797 }
798 let mut len_block = [0u8; 16];
800 let a_bits = total_len * 8;
801 len_block[..8].copy_from_slice(&a_bits.to_be_bytes());
802 for i in 0..16 {
804 y[i] ^= len_block[i];
805 }
806 y = gf128_mul(&y, &h);
807 let mut tag = [0u8; 16];
809 for i in 0..16 {
810 tag[i] = y[i] ^ e_j0[i];
811 }
812 out[..tlen].copy_from_slice(&tag[..tlen]);
813 let _ = ghash_update;
815 }
816 }
817
818 self.finalized = true;
819 Ok(tlen)
820 }
821
822 pub fn verify(&mut self, expected_tag: &[u8]) -> Result<(), Error> {
833 let tlen = self.tag_len();
834 if expected_tag.is_empty() || expected_tag.len() > tlen {
835 let mut sink = vec![0u8; tlen];
837 let _ = self.sign(&mut sink);
838 return Err(Error::VerificationFailed);
839 }
840 let mut full = vec![0u8; tlen];
841 self.sign(&mut full)?;
842
843 let mut diff = 0u8;
845 for i in 0..expected_tag.len() {
846 diff |= full[i] ^ expected_tag[i];
847 }
848 if diff == 0 {
849 Ok(())
850 } else {
851 Err(Error::VerificationFailed)
852 }
853 }
854
855 pub fn sign_to_vec(&mut self) -> Result<Vec<u8>, Error> {
857 let tlen = self.tag_len();
858 let mut out = vec![0u8; tlen];
859 self.sign(&mut out)?;
860 Ok(out)
861 }
862}
863
864fn cmac_double(input: &[u8]) -> [u8; 16] {
872 let bs = input.len();
873 debug_assert!(bs == 8 || bs == 16);
874 let rb: u8 = if bs == 16 { 0x87 } else { 0x1B };
875 let mut out = [0u8; 16];
876 let mut carry: u8 = 0;
877 for i in (0..bs).rev() {
878 let v = input[i];
879 out[i] = (v << 1) | carry;
880 carry = (v >> 7) & 1;
881 }
882 if (input[0] & 0x80) != 0 {
883 out[bs - 1] ^= rb;
884 }
885 out
886}
887
888fn left_encode(x: u64) -> Vec<u8> {
895 let mut bytes = Vec::new();
896 let be = x.to_be_bytes();
897 let first = be.iter().position(|&b| b != 0).unwrap_or(7);
900 let n = (8 - first) as u8;
901 bytes.push(n);
902 bytes.extend_from_slice(&be[first..]);
903 bytes
904}
905
906fn right_encode(x: u64) -> Vec<u8> {
909 let mut bytes = Vec::new();
910 let be = x.to_be_bytes();
911 let first = be.iter().position(|&b| b != 0).unwrap_or(7);
912 let n = (8 - first) as u8;
913 bytes.extend_from_slice(&be[first..]);
914 bytes.push(n);
915 bytes
916}
917
918fn append_encode_string(out: &mut Vec<u8>, s: &[u8]) {
920 out.extend_from_slice(&left_encode((s.len() as u64) * 8));
921 out.extend_from_slice(s);
922}
923
924fn bytepad_to(buf: &mut Vec<u8>, w: usize) {
927 let prefix = left_encode(w as u64);
931 let mut full = Vec::with_capacity(prefix.len() + buf.len());
932 full.extend_from_slice(&prefix);
933 full.extend_from_slice(buf);
934 let pad = (w - (full.len() % w)) % w;
935 full.extend(core::iter::repeat(0u8).take(pad));
936 *buf = full;
937}
938
939#[cfg(test)]
944mod tests {
945 use super::*;
946
947 fn hex(s: &str) -> Vec<u8> {
948 let s: String = s.chars().filter(|c| !c.is_whitespace()).collect();
949 (0..s.len())
950 .step_by(2)
951 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
952 .collect()
953 }
954
955 #[test]
958 fn hmac_sha256_rfc4231_tc1() {
959 let key = hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
960 let data = b"Hi There";
961 let expected = hex("b0344c61d8db38535ca8afceaf0bf12b\
962 881dc200c9833da726e9376c2e32cff7");
963
964 let mut m = Mac::new(Algorithm::HmacSha256);
965 m.init(&key).unwrap();
966 m.update(data).unwrap();
967 let tag = m.sign_to_vec().unwrap();
968 assert_eq!(tag, expected);
969 }
970
971 #[test]
972 fn hmac_sha256_rfc4231_tc2_streaming() {
973 let key = b"Jefe";
975 let expected = hex("5bdcc146bf60754e6a042426089575c7\
976 5a003f089d2739839dec58b964ec3843");
977 let data = b"what do ya want for nothing?";
978
979 let mut m = Mac::new(Algorithm::HmacSha256);
980 m.init(key).unwrap();
981 for chunk in data.chunks(3) {
982 m.update(chunk).unwrap();
983 }
984 let tag = m.sign_to_vec().unwrap();
985 assert_eq!(tag, expected);
986 }
987
988 #[test]
989 fn hmac_sha256_long_key_rfc4231_tc6() {
990 let key = vec![0xaau8; 131];
992 let data = b"Test Using Larger Than Block-Size Key - Hash Key First";
993 let expected = hex("60e431591ee0b67f0d8a26aacbf5b77f\
994 8e0bc6213728c5140546040f0ee37f54");
995
996 let mut m = Mac::new(Algorithm::HmacSha256);
997 m.init(&key).unwrap();
998 m.update(data).unwrap();
999 let tag = m.sign_to_vec().unwrap();
1000 assert_eq!(tag, expected);
1001 }
1002
1003 #[test]
1004 fn hmac_sha512_rfc4231_tc1() {
1005 let key = hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
1006 let data = b"Hi There";
1007 let expected = hex("87aa7cdea5ef619d4ff0b4241a1d6cb0\
1008 2379f4e2ce4ec2787ad0b30545e17cde\
1009 daa833b7d6b8a702038b274eaea3f4e4\
1010 be9d914eeb61f1702e696c203a126854");
1011
1012 let mut m = Mac::new(Algorithm::HmacSha512);
1013 m.init(&key).unwrap();
1014 m.update(data).unwrap();
1015 assert_eq!(m.sign_to_vec().unwrap(), expected);
1016 }
1017
1018 #[test]
1019 fn hmac_sha1_rfc2202_tc1() {
1020 let key = hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
1022 let data = b"Hi There";
1023 let expected = hex("b617318655057264e28bc0b6fb378c8ef146be00");
1024
1025 let mut m = Mac::new(Algorithm::HmacSha1);
1026 m.init(&key).unwrap();
1027 m.update(data).unwrap();
1028 assert_eq!(m.sign_to_vec().unwrap(), expected);
1029 }
1030
1031 #[test]
1035 fn cmac_aes128_rfc4493_empty() {
1036 let key = hex("2b7e151628aed2a6abf7158809cf4f3c");
1037 let expected = hex("bb1d6929e95937287fa37d129b756746");
1038
1039 let mut m = Mac::new(Algorithm::CmacAes128);
1040 m.init(&key).unwrap();
1041 m.update(b"").unwrap();
1042 assert_eq!(m.sign_to_vec().unwrap(), expected);
1043 }
1044
1045 #[test]
1047 fn cmac_aes128_rfc4493_one_block() {
1048 let key = hex("2b7e151628aed2a6abf7158809cf4f3c");
1049 let m_bytes = hex("6bc1bee22e409f96e93d7e117393172a");
1050 let expected = hex("070a16b46b4d4144f79bdd9dd04a287c");
1051
1052 let mut m = Mac::new(Algorithm::CmacAes128);
1053 m.init(&key).unwrap();
1054 m.update(&m_bytes).unwrap();
1055 assert_eq!(m.sign_to_vec().unwrap(), expected);
1056 }
1057
1058 #[test]
1060 fn cmac_aes128_rfc4493_40bytes() {
1061 let key = hex("2b7e151628aed2a6abf7158809cf4f3c");
1062 let m_bytes = hex("6bc1bee22e409f96e93d7e117393172a\
1063 ae2d8a571e03ac9c9eb76fac45af8e51\
1064 30c81c46a35ce411");
1065 let expected = hex("dfa66747de9ae63030ca32611497c827");
1066
1067 let mut m = Mac::new(Algorithm::CmacAes128);
1068 m.init(&key).unwrap();
1069 m.update(&m_bytes[..7]).unwrap();
1071 m.update(&m_bytes[7..23]).unwrap();
1072 m.update(&m_bytes[23..]).unwrap();
1073 assert_eq!(m.sign_to_vec().unwrap(), expected);
1074 }
1075
1076 #[test]
1078 fn cmac_aes128_rfc4493_64bytes() {
1079 let key = hex("2b7e151628aed2a6abf7158809cf4f3c");
1080 let m_bytes = hex("6bc1bee22e409f96e93d7e117393172a\
1081 ae2d8a571e03ac9c9eb76fac45af8e51\
1082 30c81c46a35ce411e5fbc1191a0a52ef\
1083 f69f2445df4f9b17ad2b417be66c3710");
1084 let expected = hex("51f0bebf7e3b9d92fc49741779363cfe");
1085
1086 let mut m = Mac::new(Algorithm::CmacAes128);
1087 m.init(&key).unwrap();
1088 m.update(&m_bytes).unwrap();
1089 assert_eq!(m.sign_to_vec().unwrap(), expected);
1090 }
1091
1092 #[test]
1097 fn kmac128_sample1() {
1098 let key = hex("404142434445464748494a4b4c4d4e4f\
1100 505152535455565758595a5b5c5d5e5f");
1101 let data = hex("00010203");
1102 let expected = hex("e5780b0d3ea6f7d3a429c5706aa43a00\
1103 fadbd7d49628839e3187243f456ee14e");
1104
1105 let mut m = Mac::new(Algorithm::Kmac128);
1106 m.init(&key).unwrap();
1107 m.update(&data).unwrap();
1108 assert_eq!(m.sign_to_vec().unwrap(), expected);
1109 }
1110
1111 #[test]
1112 fn kmac128_sample2_with_custom() {
1113 let key = hex("404142434445464748494a4b4c4d4e4f\
1115 505152535455565758595a5b5c5d5e5f");
1116 let data = hex("00010203");
1117 let custom = b"My Tagged Application";
1118 let expected = hex("3b1fba963cd8b0b59e8c1a6d71888b71\
1119 43651af8ba0a7070c0979e2811324aa5");
1120
1121 let mut m = Mac::new(Algorithm::Kmac128);
1122 m.init_kmac(&key, custom).unwrap();
1123 m.update(&data).unwrap();
1124 assert_eq!(m.sign_to_vec().unwrap(), expected);
1125 }
1126
1127 #[test]
1128 fn kmac256_sample4_with_custom() {
1129 let key = hex("404142434445464748494a4b4c4d4e4f\
1132 505152535455565758595a5b5c5d5e5f");
1133 let data = hex("00010203");
1134 let custom = b"My Tagged Application";
1135 let expected = hex("20c570c31346f703c9ac36c61c03cb64\
1136 c3970d0cfc787e9b79599d273a68d2f7\
1137 f69d4cc3de9d104a351689f27cf6f595\
1138 1f0103f33f4f24871024d9c27773a8dd");
1139
1140 let mut m = Mac::new(Algorithm::Kmac256);
1141 m.init_kmac(&key, custom).unwrap();
1142 m.update(&data).unwrap();
1143 assert_eq!(m.sign_to_vec().unwrap(), expected);
1144 }
1145
1146 #[test]
1151 fn gmac_aes128_matches_gcm_empty_plaintext() {
1152 use crate::cipher::aes::Aes128;
1153 use crate::cipher::modes::Gcm;
1154 let key = hex("feffe9928665731c6d6a8f9467308308");
1155 let nonce_bytes = hex("cafebabefacedbaddecaf888");
1156 let nonce: [u8; 12] = nonce_bytes.clone().try_into().unwrap();
1157 let aad = hex("d9313225f88406e5a55909c5aff5269a\
1158 86a7a9531534f7da2e4c303d8a318a72\
1159 1c3c0c95956809532fcf0e2449a6b525");
1160
1161 let cipher = Aes128::new(&key);
1162 let (_ct, tag_ref) = Gcm::encrypt(&cipher, &nonce, &aad, &[]);
1163
1164 let mut m = Mac::new(Algorithm::GmacAes128);
1165 m.init_with_nonce(&key, &nonce_bytes).unwrap();
1166 for chunk in aad.chunks(7) {
1168 m.update(chunk).unwrap();
1169 }
1170 let tag = m.sign_to_vec().unwrap();
1171 assert_eq!(tag.len(), 16);
1172 assert_eq!(tag, tag_ref.to_vec());
1173 }
1174
1175 #[test]
1176 fn gmac_verify_truncated() {
1177 let key = hex("feffe9928665731c6d6a8f9467308308");
1178 let nonce = hex("cafebabefacedbaddecaf888");
1179 let aad = b"some authenticated data";
1180
1181 let mut signer = Mac::new(Algorithm::GmacAes128);
1182 signer.init_with_nonce(&key, &nonce).unwrap();
1183 signer.update(aad).unwrap();
1184 let full_tag = signer.sign_to_vec().unwrap();
1185
1186 let truncated = &full_tag[..12];
1188 let mut verifier = Mac::new(Algorithm::GmacAes128);
1189 verifier.init_with_nonce(&key, &nonce).unwrap();
1190 verifier.update(aad).unwrap();
1191 assert_eq!(verifier.verify(truncated), Ok(()));
1192
1193 let mut bad = full_tag.clone();
1195 bad[0] ^= 0xFF;
1196 let mut verifier = Mac::new(Algorithm::GmacAes128);
1197 verifier.init_with_nonce(&key, &nonce).unwrap();
1198 verifier.update(aad).unwrap();
1199 assert_eq!(verifier.verify(&bad[..12]), Err(Error::VerificationFailed));
1200 }
1201
1202 #[test]
1205 fn round_trip_all_hmac_and_cmac() {
1206 let key128 = [0x42u8; 16];
1207 let key192 = [0x42u8; 24];
1208 let key256 = [0x42u8; 32];
1209
1210 let cases: &[(Algorithm, &[u8])] = &[
1211 (Algorithm::HmacSha1, b"hmac-sha1-key-here"),
1212 (Algorithm::HmacSha256, b"hmac-sha256-key-here"),
1213 (Algorithm::HmacSha384, b"hmac-sha384-key-here"),
1214 (Algorithm::HmacSha512, b"hmac-sha512-key-here"),
1215 (Algorithm::HmacSha3_256, b"hmac-sha3-256-key"),
1216 (Algorithm::HmacSha3_384, b"hmac-sha3-384-key"),
1217 (Algorithm::HmacSha3_512, b"hmac-sha3-512-key"),
1218 (Algorithm::HmacRipemd160, b"hmac-ripemd160-key"),
1219 (Algorithm::CmacAes128, &key128),
1220 (Algorithm::CmacAes192, &key192),
1221 (Algorithm::CmacAes256, &key256),
1222 (Algorithm::CmacTripleDes, &key192),
1223 ];
1224
1225 for (algo, key) in cases {
1226 let mut signer = Mac::new(*algo);
1227 signer.init(key).unwrap();
1228 signer.update(b"the quick brown fox jumps over the lazy dog").unwrap();
1229 let tag = signer.sign_to_vec().unwrap();
1230
1231 let mut verifier = Mac::new(*algo);
1232 verifier.init(key).unwrap();
1233 verifier.update(b"the quick brown fox jumps over the lazy dog").unwrap();
1234 assert_eq!(verifier.verify(&tag), Ok(()), "{:?}", algo);
1235
1236 let mut bad = tag.clone();
1238 bad[0] ^= 0x01;
1239 let mut verifier = Mac::new(*algo);
1240 verifier.init(key).unwrap();
1241 verifier.update(b"the quick brown fox jumps over the lazy dog").unwrap();
1242 assert_eq!(verifier.verify(&bad), Err(Error::VerificationFailed), "{:?}", algo);
1243 }
1244 }
1245
1246 #[test]
1249 fn hmac_init_after_use_resets() {
1250 let mut m = Mac::new(Algorithm::HmacSha256);
1251 m.init(b"first key").unwrap();
1252 m.update(b"first message").unwrap();
1253 let _ = m.sign_to_vec().unwrap();
1254
1255 m.init(b"second key").unwrap();
1257 m.update(b"second message").unwrap();
1258 let tag = m.sign_to_vec().unwrap();
1259
1260 let mut ref_m = Mac::new(Algorithm::HmacSha256);
1262 ref_m.init(b"second key").unwrap();
1263 ref_m.update(b"second message").unwrap();
1264 assert_eq!(tag, ref_m.sign_to_vec().unwrap());
1265 }
1266
1267 #[test]
1268 fn wrong_init_variant_rejected() {
1269 let mut m = Mac::new(Algorithm::GmacAes128);
1270 assert_eq!(m.init(&[0u8; 16]), Err(Error::WrongInitVariant));
1271
1272 let mut m = Mac::new(Algorithm::HmacSha256);
1273 assert_eq!(m.init_with_nonce(b"k", &[0u8; 12]), Err(Error::WrongInitVariant));
1274
1275 let mut m = Mac::new(Algorithm::HmacSha256);
1276 assert_eq!(m.init_kmac(b"k", b""), Err(Error::WrongInitVariant));
1277 }
1278
1279 #[test]
1280 fn cmac_invalid_key_len() {
1281 let mut m = Mac::new(Algorithm::CmacAes128);
1282 assert_eq!(m.init(&[0u8; 17]), Err(Error::InvalidKeyLen));
1283 }
1284
1285 #[test]
1286 fn gmac_invalid_nonce_len() {
1287 let mut m = Mac::new(Algorithm::GmacAes128);
1288 assert_eq!(m.init_with_nonce(&[0u8; 16], &[0u8; 11]), Err(Error::InvalidNonceLen));
1289 }
1290
1291 #[test]
1292 fn output_too_small() {
1293 let mut m = Mac::new(Algorithm::HmacSha256);
1294 m.init(b"k").unwrap();
1295 m.update(b"data").unwrap();
1296 let mut small = [0u8; 8];
1297 assert!(matches!(m.sign(&mut small), Err(Error::OutputBufferTooSmall { .. })));
1298 }
1299
1300 #[test]
1301 fn verify_rejects_empty_or_too_long() {
1302 let mut m = Mac::new(Algorithm::HmacSha256);
1303 m.init(b"k").unwrap();
1304 m.update(b"d").unwrap();
1305 assert_eq!(m.verify(&[]), Err(Error::VerificationFailed));
1306
1307 let mut m = Mac::new(Algorithm::HmacSha256);
1308 m.init(b"k").unwrap();
1309 m.update(b"d").unwrap();
1310 assert_eq!(m.verify(&[0u8; 33]), Err(Error::VerificationFailed));
1311 }
1312}