1#![no_std]
36#![allow(
37 non_snake_case,
38 clippy::cast_lossless,
39 clippy::eq_op,
40 clippy::identity_op,
41 clippy::many_single_char_names,
42 clippy::unreadable_literal
43)]
44
45#[inline(always)]
46fn load_be(base: &[u8], offset: usize) -> u32 {
47 let addr = &base[offset..];
48 (addr[3] as u32) | (addr[2] as u32) << 8 | (addr[1] as u32) << 16 | (addr[0] as u32) << 24
49}
50
51#[inline(always)]
52fn store_be(base: &mut [u8], offset: usize, x: u32) {
53 let addr = &mut base[offset..];
54 addr[3] = x as u8;
55 addr[2] = (x >> 8) as u8;
56 addr[1] = (x >> 16) as u8;
57 addr[0] = (x >> 24) as u8;
58}
59
60fn verify(x: &[u8], y: &[u8]) -> bool {
61 if x.len() != y.len() {
62 return false;
63 }
64 let mut v: u32 = 0;
65
66 #[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
67 {
68 let (mut h1, mut h2) = (0u32, 0u32);
69 for (b1, b2) in x.iter().zip(y.iter()) {
70 h1 ^= (h1 << 5).wrapping_add((h1 >> 2) ^ *b1 as u32);
71 h2 ^= (h2 << 5).wrapping_add((h2 >> 2) ^ *b2 as u32);
72 }
73 v |= h1 ^ h2;
74 }
75 for (a, b) in x.iter().zip(y.iter()) {
76 v |= (a ^ b) as u32;
77 }
78 let v = unsafe { core::ptr::read_volatile(&v) };
79 v == 0
80}
81
82struct W([u32; 16]);
83
84#[derive(Copy, Clone)]
85struct State([u32; 8]);
86
87impl W {
88 fn new(input: &[u8]) -> Self {
89 let mut w = [0u32; 16];
90 for (i, e) in w.iter_mut().enumerate() {
91 *e = load_be(input, i * 4)
92 }
93 W(w)
94 }
95
96 #[inline(always)]
97 fn Ch(x: u32, y: u32, z: u32) -> u32 {
98 (x & y) ^ (!x & z)
99 }
100
101 #[inline(always)]
102 fn Maj(x: u32, y: u32, z: u32) -> u32 {
103 (x & y) ^ (x & z) ^ (y & z)
104 }
105
106 #[inline(always)]
107 fn Sigma0(x: u32) -> u32 {
108 x.rotate_right(2) ^ x.rotate_right(13) ^ x.rotate_right(22)
109 }
110
111 #[inline(always)]
112 fn Sigma1(x: u32) -> u32 {
113 x.rotate_right(6) ^ x.rotate_right(11) ^ x.rotate_right(25)
114 }
115
116 #[inline(always)]
117 fn sigma0(x: u32) -> u32 {
118 x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3)
119 }
120
121 #[inline(always)]
122 fn sigma1(x: u32) -> u32 {
123 x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10)
124 }
125
126 #[cfg_attr(feature = "opt_size", inline(never))]
127 #[cfg_attr(not(feature = "opt_size"), inline(always))]
128 fn M(&mut self, a: usize, b: usize, c: usize, d: usize) {
129 let w = &mut self.0;
130 w[a] = w[a]
131 .wrapping_add(Self::sigma1(w[b]))
132 .wrapping_add(w[c])
133 .wrapping_add(Self::sigma0(w[d]));
134 }
135
136 #[inline]
137 fn expand(&mut self) {
138 self.M(0, (0 + 14) & 15, (0 + 9) & 15, (0 + 1) & 15);
139 self.M(1, (1 + 14) & 15, (1 + 9) & 15, (1 + 1) & 15);
140 self.M(2, (2 + 14) & 15, (2 + 9) & 15, (2 + 1) & 15);
141 self.M(3, (3 + 14) & 15, (3 + 9) & 15, (3 + 1) & 15);
142 self.M(4, (4 + 14) & 15, (4 + 9) & 15, (4 + 1) & 15);
143 self.M(5, (5 + 14) & 15, (5 + 9) & 15, (5 + 1) & 15);
144 self.M(6, (6 + 14) & 15, (6 + 9) & 15, (6 + 1) & 15);
145 self.M(7, (7 + 14) & 15, (7 + 9) & 15, (7 + 1) & 15);
146 self.M(8, (8 + 14) & 15, (8 + 9) & 15, (8 + 1) & 15);
147 self.M(9, (9 + 14) & 15, (9 + 9) & 15, (9 + 1) & 15);
148 self.M(10, (10 + 14) & 15, (10 + 9) & 15, (10 + 1) & 15);
149 self.M(11, (11 + 14) & 15, (11 + 9) & 15, (11 + 1) & 15);
150 self.M(12, (12 + 14) & 15, (12 + 9) & 15, (12 + 1) & 15);
151 self.M(13, (13 + 14) & 15, (13 + 9) & 15, (13 + 1) & 15);
152 self.M(14, (14 + 14) & 15, (14 + 9) & 15, (14 + 1) & 15);
153 self.M(15, (15 + 14) & 15, (15 + 9) & 15, (15 + 1) & 15);
154 }
155
156 #[cfg_attr(feature = "opt_size", inline(never))]
157 #[cfg_attr(not(feature = "opt_size"), inline(always))]
158 fn F(&mut self, state: &mut State, i: usize, k: u32) {
159 let t = &mut state.0;
160 t[(16 - i + 7) & 7] = t[(16 - i + 7) & 7]
161 .wrapping_add(Self::Sigma1(t[(16 - i + 4) & 7]))
162 .wrapping_add(Self::Ch(
163 t[(16 - i + 4) & 7],
164 t[(16 - i + 5) & 7],
165 t[(16 - i + 6) & 7],
166 ))
167 .wrapping_add(k)
168 .wrapping_add(self.0[i]);
169 t[(16 - i + 3) & 7] = t[(16 - i + 3) & 7].wrapping_add(t[(16 - i + 7) & 7]);
170 t[(16 - i + 7) & 7] = t[(16 - i + 7) & 7]
171 .wrapping_add(Self::Sigma0(t[(16 - i + 0) & 7]))
172 .wrapping_add(Self::Maj(
173 t[(16 - i + 0) & 7],
174 t[(16 - i + 1) & 7],
175 t[(16 - i + 2) & 7],
176 ));
177 }
178
179 fn G(&mut self, state: &mut State, s: usize) {
180 const ROUND_CONSTANTS: [u32; 64] = [
181 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
182 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
183 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
184 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
185 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
186 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
187 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
188 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
189 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
190 0xc67178f2,
191 ];
192 let rc = &ROUND_CONSTANTS[s * 16..];
193 self.F(state, 0, rc[0]);
194 self.F(state, 1, rc[1]);
195 self.F(state, 2, rc[2]);
196 self.F(state, 3, rc[3]);
197 self.F(state, 4, rc[4]);
198 self.F(state, 5, rc[5]);
199 self.F(state, 6, rc[6]);
200 self.F(state, 7, rc[7]);
201 self.F(state, 8, rc[8]);
202 self.F(state, 9, rc[9]);
203 self.F(state, 10, rc[10]);
204 self.F(state, 11, rc[11]);
205 self.F(state, 12, rc[12]);
206 self.F(state, 13, rc[13]);
207 self.F(state, 14, rc[14]);
208 self.F(state, 15, rc[15]);
209 }
210}
211
212impl State {
213 fn new() -> Self {
214 const IV: [u8; 32] = [
215 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f,
216 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab,
217 0x5b, 0xe0, 0xcd, 0x19,
218 ];
219 let mut t = [0u32; 8];
220 for (i, e) in t.iter_mut().enumerate() {
221 *e = load_be(&IV, i * 4)
222 }
223 State(t)
224 }
225
226 #[inline(always)]
227 fn add(&mut self, x: &State) {
228 let sx = &mut self.0;
229 let ex = &x.0;
230 sx[0] = sx[0].wrapping_add(ex[0]);
231 sx[1] = sx[1].wrapping_add(ex[1]);
232 sx[2] = sx[2].wrapping_add(ex[2]);
233 sx[3] = sx[3].wrapping_add(ex[3]);
234 sx[4] = sx[4].wrapping_add(ex[4]);
235 sx[5] = sx[5].wrapping_add(ex[5]);
236 sx[6] = sx[6].wrapping_add(ex[6]);
237 sx[7] = sx[7].wrapping_add(ex[7]);
238 }
239
240 fn store(&self, out: &mut [u8]) {
241 for (i, &e) in self.0.iter().enumerate() {
242 store_be(out, i * 4, e);
243 }
244 }
245
246 fn blocks(&mut self, mut input: &[u8]) -> usize {
247 let mut t = *self;
248 let mut inlen = input.len();
249 while inlen >= 64 {
250 let mut w = W::new(input);
251 w.G(&mut t, 0);
252 w.expand();
253 w.G(&mut t, 1);
254 w.expand();
255 w.G(&mut t, 2);
256 w.expand();
257 w.G(&mut t, 3);
258 t.add(self);
259 self.0 = t.0;
260 input = &input[64..];
261 inlen -= 64;
262 }
263 inlen
264 }
265}
266
267#[derive(Copy, Clone)]
268pub struct Hash {
287 state: State,
288 w: [u8; 64],
289 r: usize,
290 len: usize,
291}
292
293impl Hash {
294 pub fn new() -> Hash {
296 Hash {
297 state: State::new(),
298 r: 0,
299 w: [0u8; 64],
300 len: 0,
301 }
302 }
303
304 fn _update(&mut self, input: impl AsRef<[u8]>) {
305 let input = input.as_ref();
306 let mut n = input.len();
307 self.len += n;
308 let av = 64 - self.r;
309 let tc = ::core::cmp::min(n, av);
310 self.w[self.r..self.r + tc].copy_from_slice(&input[0..tc]);
311 self.r += tc;
312 n -= tc;
313 let pos = tc;
314 if self.r == 64 {
315 self.state.blocks(&self.w);
316 self.r = 0;
317 }
318 if self.r == 0 && n > 0 {
319 let rb = self.state.blocks(&input[pos..]);
320 if rb > 0 {
321 self.w[..rb].copy_from_slice(&input[pos + n - rb..]);
322 self.r = rb;
323 }
324 }
325 }
326
327 pub fn update(&mut self, input: impl AsRef<[u8]>) {
340 self._update(input)
341 }
342
343 pub fn finalize(mut self) -> [u8; 32] {
355 let mut padded = [0u8; 128];
356 padded[..self.r].copy_from_slice(&self.w[..self.r]);
357 padded[self.r] = 0x80;
358 let r = if self.r < 56 { 64 } else { 128 };
359 let bits = self.len * 8;
360 for i in 0..8 {
361 padded[r - 8 + i] = (bits as u64 >> (56 - i * 8)) as u8;
362 }
363 self.state.blocks(&padded[..r]);
364 let mut out = [0u8; 32];
365 self.state.store(&mut out);
366 out
367 }
368
369 pub fn finalize_verify(self, expected: &[u8; 32]) -> bool {
387 let out = self.finalize();
388 verify(&out, expected)
389 }
390
391 pub fn verify(input: impl AsRef<[u8]>, expected: &[u8; 32]) -> bool {
406 let hash = Self::hash(input.as_ref());
407 verify(&hash, expected)
408 }
409
410 pub fn verify_with_ref(self, expected: &[u8]) -> bool {
444 if expected.len() != 32 {
445 return false;
446 }
447 let out = self.finalize();
448 verify(&out, expected)
449 }
450
451 pub fn hash(input: &[u8]) -> [u8; 32] {
461 let mut h = Hash::new();
462 h.update(input);
463 h.finalize()
464 }
465}
466
467impl Default for Hash {
468 fn default() -> Self {
469 Self::new()
470 }
471}
472
473#[derive(Clone)]
474pub struct HMAC {
493 ih: Hash,
494 padded: [u8; 64],
495}
496
497impl HMAC {
498 pub fn mac(input: impl AsRef<[u8]>, k: impl AsRef<[u8]>) -> [u8; 32] {
517 let input = input.as_ref();
518 let k = k.as_ref();
519 let mut hk = [0u8; 32];
520 let k2 = if k.len() > 64 {
521 hk.copy_from_slice(&Hash::hash(k));
522 &hk
523 } else {
524 k
525 };
526 let mut padded = [0x36; 64];
527 for (p, &k) in padded.iter_mut().zip(k2.iter()) {
528 *p ^= k;
529 }
530 let mut ih = Hash::new();
531 ih.update(&padded[..]);
532 ih.update(input);
533
534 for p in padded.iter_mut() {
535 *p ^= 0x6a;
536 }
537 let mut oh = Hash::new();
538 oh.update(&padded[..]);
539 oh.update(ih.finalize());
540 oh.finalize()
541 }
542
543 pub fn new(k: impl AsRef<[u8]>) -> HMAC {
555 let k = k.as_ref();
556 let mut hk = [0u8; 32];
557 let k2 = if k.len() > 64 {
558 hk.copy_from_slice(&Hash::hash(k));
559 &hk
560 } else {
561 k
562 };
563 let mut padded = [0x36; 64];
564 for (p, &k) in padded.iter_mut().zip(k2.iter()) {
565 *p ^= k;
566 }
567 let mut ih = Hash::new();
568 ih.update(&padded[..]);
569 HMAC { ih, padded }
570 }
571
572 pub fn update(&mut self, input: impl AsRef<[u8]>) {
585 self.ih.update(input);
586 }
587
588 pub fn finalize(mut self) -> [u8; 32] {
600 for p in self.padded.iter_mut() {
601 *p ^= 0x6a;
602 }
603 let mut oh = Hash::new();
604 oh.update(&self.padded[..]);
605 oh.update(self.ih.finalize());
606 oh.finalize()
607 }
608
609 pub fn finalize_verify(self, expected: &[u8; 32]) -> bool {
627 let out = self.finalize();
628 verify(&out, expected)
629 }
630
631 pub fn verify(input: impl AsRef<[u8]>, k: impl AsRef<[u8]>, expected: &[u8; 32]) -> bool {
656 let mac = Self::mac(input, k);
657 verify(&mac, expected)
658 }
659}
660
661pub struct HKDF;
682
683impl HKDF {
684 pub fn extract(salt: impl AsRef<[u8]>, ikm: impl AsRef<[u8]>) -> [u8; 32] {
703 HMAC::mac(ikm, salt)
704 }
705
706 pub fn expand(out: &mut [u8], prk: impl AsRef<[u8]>, info: impl AsRef<[u8]>) {
728 let info = info.as_ref();
729 let mut counter: u8 = 1;
730 assert!(out.len() < 0xff * 32);
731 let mut i: usize = 0;
732 while i < out.len() {
733 let mut hmac = HMAC::new(&prk);
734 if i != 0 {
735 hmac.update(&out[i - 32..][..32]);
736 }
737 hmac.update(info);
738 hmac.update([counter]);
739 let left = core::cmp::min(32, out.len() - i);
740 out[i..][..left].copy_from_slice(&hmac.finalize()[..left]);
741 counter += 1;
742 i += 32;
743 }
744 }
745}
746
747#[cfg(feature = "traits010")]
749pub type WrappedHash = digest010::core_api::CoreWrapper<Hash>;
750
751#[cfg(feature = "traits010")]
752mod digest_trait010 {
753 use core::fmt;
754
755 use digest010::{
756 block_buffer::Eager,
757 const_oid::{AssociatedOid, ObjectIdentifier},
758 consts::{U32, U64},
759 core_api::{
760 AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore,
761 OutputSizeUser, Reset, UpdateCore,
762 },
763 FixedOutput, FixedOutputReset, HashMarker, Output, Update,
764 };
765
766 use super::Hash;
767
768 impl AssociatedOid for Hash {
769 const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.1");
770 }
771
772 impl AlgorithmName for Hash {
773 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
774 f.write_str("Sha256")
775 }
776 }
777
778 impl HashMarker for Hash {}
779
780 impl BufferKindUser for Hash {
781 type BufferKind = Eager;
782 }
783
784 impl BlockSizeUser for Hash {
785 type BlockSize = U64;
786 }
787
788 impl OutputSizeUser for Hash {
789 type OutputSize = U32;
790 }
791
792 impl UpdateCore for Hash {
793 #[inline]
794 fn update_blocks(&mut self, blocks: &[Block<Self>]) {
795 for block in blocks {
796 self._update(block);
797 }
798 }
799 }
800
801 impl Update for Hash {
802 #[inline]
803 fn update(&mut self, data: &[u8]) {
804 self._update(data);
805 }
806 }
807
808 impl FixedOutputCore for Hash {
809 fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
810 self._update(buffer.get_data());
811 self.finalize_into(out);
812 }
813 }
814
815 impl FixedOutput for Hash {
816 fn finalize_into(self, out: &mut Output<Self>) {
817 let h = self.finalize();
818 out.copy_from_slice(&h);
819 }
820 }
821
822 impl Reset for Hash {
823 fn reset(&mut self) {
824 *self = Self::new()
825 }
826 }
827
828 impl FixedOutputReset for Hash {
829 fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
830 self.finalize_into(out);
831 self.reset();
832 }
833 }
834}
835
836#[cfg(feature = "traits09")]
837mod digest_trait09 {
838 use digest09::consts::{U32, U64};
839 use digest09::{BlockInput, FixedOutputDirty, Output, Reset, Update};
840
841 use super::Hash;
842
843 impl BlockInput for Hash {
844 type BlockSize = U64;
845 }
846
847 impl Update for Hash {
848 fn update(&mut self, input: impl AsRef<[u8]>) {
849 self._update(input)
850 }
851 }
852
853 impl FixedOutputDirty for Hash {
854 type OutputSize = U32;
855
856 fn finalize_into_dirty(&mut self, out: &mut Output<Self>) {
857 let h = self.finalize();
858 out.copy_from_slice(&h);
859 }
860 }
861
862 impl Reset for Hash {
863 fn reset(&mut self) {
864 *self = Self::new()
865 }
866 }
867}
868
869#[test]
870fn main() {
871 let h = HMAC::mac([], [0u8; 32]);
872 assert_eq!(
873 &h[..],
874 &[
875 182, 19, 103, 154, 8, 20, 217, 236, 119, 47, 149, 215, 120, 195, 95, 197, 255, 22, 151,
876 196, 147, 113, 86, 83, 198, 199, 18, 20, 66, 146, 197, 173
877 ]
878 );
879
880 let h = HMAC::mac([42u8; 69], []);
881 assert_eq!(
882 &h[..],
883 &[
884 225, 88, 35, 8, 78, 185, 165, 6, 235, 124, 28, 250, 112, 124, 159, 119, 159, 88, 184,
885 61, 7, 37, 166, 229, 71, 154, 83, 153, 151, 181, 182, 72
886 ]
887 );
888
889 let h = HMAC::mac([69u8; 250], [42u8; 50]);
890 assert_eq!(
891 &h[..],
892 &[
893 112, 156, 120, 216, 86, 25, 79, 210, 155, 193, 32, 120, 116, 134, 237, 14, 198, 1, 64,
894 41, 124, 196, 103, 91, 109, 216, 36, 133, 4, 234, 218, 228
895 ]
896 );
897
898 let mut s = HMAC::new([42u8; 50]);
899 s.update([69u8; 150]);
900 s.update([69u8; 100]);
901 let h = s.finalize();
902 assert_eq!(
903 &h[..],
904 &[
905 112, 156, 120, 216, 86, 25, 79, 210, 155, 193, 32, 120, 116, 134, 237, 14, 198, 1, 64,
906 41, 124, 196, 103, 91, 109, 216, 36, 133, 4, 234, 218, 228
907 ]
908 );
909
910 let expected_mac = HMAC::mac([69u8; 250], [42u8; 50]);
912 let mut hmac = HMAC::new([42u8; 50]);
913 hmac.update([69u8; 250]);
914 assert!(hmac.finalize_verify(&expected_mac));
915
916 let mut hmac = HMAC::new([42u8; 50]);
917 hmac.update([69u8; 251]); assert!(!hmac.finalize_verify(&expected_mac));
919
920 assert!(HMAC::verify([69u8; 250], [42u8; 50], &expected_mac));
922 assert!(!HMAC::verify([69u8; 251], [42u8; 50], &expected_mac)); assert!(!HMAC::verify([69u8; 250], [43u8; 50], &expected_mac)); let expected_hash = Hash::hash(&[42u8; 123]);
927 assert!(Hash::verify(&[42u8; 123], &expected_hash));
928 assert!(!Hash::verify(&[42u8; 124], &expected_hash));
929
930 let mut hasher = Hash::new();
932 hasher.update(&[42u8; 123]);
933 assert!(hasher.finalize_verify(&expected_hash));
934
935 let mut hasher = Hash::new();
936 hasher.update(&[42u8; 124]); assert!(!hasher.finalize_verify(&expected_hash));
938
939 let ikm = [0x0bu8; 22];
940 let salt = [
941 0x00u8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
942 ];
943 let context = [0xf0u8, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9];
944 let prk = HKDF::extract(salt, ikm);
945 let mut k = [0u8; 40];
946 HKDF::expand(&mut k, prk, context);
947 assert_eq!(
948 &k[..],
949 &[
950 60, 178, 95, 37, 250, 172, 213, 122, 144, 67, 79, 100, 208, 54, 47, 42, 45, 45, 10,
951 144, 207, 26, 90, 76, 93, 176, 45, 86, 236, 196, 197, 191, 52, 0, 114, 8, 213, 184,
952 135, 24
953 ]
954 );
955}