1#![no_std]
5#![allow(
6 non_snake_case,
7 clippy::cast_lossless,
8 clippy::eq_op,
9 clippy::identity_op,
10 clippy::many_single_char_names,
11 clippy::unreadable_literal
12)]
13
14#[inline(always)]
15fn load_be(base: &[u8], offset: usize) -> u32 {
16 let addr = &base[offset..];
17 (addr[3] as u32) | (addr[2] as u32) << 8 | (addr[1] as u32) << 16 | (addr[0] as u32) << 24
18}
19
20#[inline(always)]
21fn store_be(base: &mut [u8], offset: usize, x: u32) {
22 let addr = &mut base[offset..];
23 addr[3] = x as u8;
24 addr[2] = (x >> 8) as u8;
25 addr[1] = (x >> 16) as u8;
26 addr[0] = (x >> 24) as u8;
27}
28
29struct W([u32; 16]);
30
31#[derive(Copy, Clone)]
32struct State([u32; 8]);
33
34impl W {
35 fn new(input: &[u8]) -> Self {
36 let mut w = [0u32; 16];
37 for (i, e) in w.iter_mut().enumerate() {
38 *e = load_be(input, i * 4)
39 }
40 W(w)
41 }
42
43 #[inline(always)]
44 fn Ch(x: u32, y: u32, z: u32) -> u32 {
45 (x & y) ^ (!x & z)
46 }
47
48 #[inline(always)]
49 fn Maj(x: u32, y: u32, z: u32) -> u32 {
50 (x & y) ^ (x & z) ^ (y & z)
51 }
52
53 #[inline(always)]
54 fn Sigma0(x: u32) -> u32 {
55 x.rotate_right(2) ^ x.rotate_right(13) ^ x.rotate_right(22)
56 }
57
58 #[inline(always)]
59 fn Sigma1(x: u32) -> u32 {
60 x.rotate_right(6) ^ x.rotate_right(11) ^ x.rotate_right(25)
61 }
62
63 #[inline(always)]
64 fn sigma0(x: u32) -> u32 {
65 x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3)
66 }
67
68 #[inline(always)]
69 fn sigma1(x: u32) -> u32 {
70 x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10)
71 }
72
73 #[cfg_attr(feature = "opt_size", inline(never))]
74 #[cfg_attr(not(feature = "opt_size"), inline(always))]
75 fn M(&mut self, a: usize, b: usize, c: usize, d: usize) {
76 let w = &mut self.0;
77 w[a] = w[a]
78 .wrapping_add(Self::sigma1(w[b]))
79 .wrapping_add(w[c])
80 .wrapping_add(Self::sigma0(w[d]));
81 }
82
83 #[inline]
84 fn expand(&mut self) {
85 self.M(0, (0 + 14) & 15, (0 + 9) & 15, (0 + 1) & 15);
86 self.M(1, (1 + 14) & 15, (1 + 9) & 15, (1 + 1) & 15);
87 self.M(2, (2 + 14) & 15, (2 + 9) & 15, (2 + 1) & 15);
88 self.M(3, (3 + 14) & 15, (3 + 9) & 15, (3 + 1) & 15);
89 self.M(4, (4 + 14) & 15, (4 + 9) & 15, (4 + 1) & 15);
90 self.M(5, (5 + 14) & 15, (5 + 9) & 15, (5 + 1) & 15);
91 self.M(6, (6 + 14) & 15, (6 + 9) & 15, (6 + 1) & 15);
92 self.M(7, (7 + 14) & 15, (7 + 9) & 15, (7 + 1) & 15);
93 self.M(8, (8 + 14) & 15, (8 + 9) & 15, (8 + 1) & 15);
94 self.M(9, (9 + 14) & 15, (9 + 9) & 15, (9 + 1) & 15);
95 self.M(10, (10 + 14) & 15, (10 + 9) & 15, (10 + 1) & 15);
96 self.M(11, (11 + 14) & 15, (11 + 9) & 15, (11 + 1) & 15);
97 self.M(12, (12 + 14) & 15, (12 + 9) & 15, (12 + 1) & 15);
98 self.M(13, (13 + 14) & 15, (13 + 9) & 15, (13 + 1) & 15);
99 self.M(14, (14 + 14) & 15, (14 + 9) & 15, (14 + 1) & 15);
100 self.M(15, (15 + 14) & 15, (15 + 9) & 15, (15 + 1) & 15);
101 }
102
103 #[cfg_attr(feature = "opt_size", inline(never))]
104 #[cfg_attr(not(feature = "opt_size"), inline(always))]
105 fn F(&mut self, state: &mut State, i: usize, k: u32) {
106 let t = &mut state.0;
107 t[(16 - i + 7) & 7] = t[(16 - i + 7) & 7]
108 .wrapping_add(Self::Sigma1(t[(16 - i + 4) & 7]))
109 .wrapping_add(Self::Ch(
110 t[(16 - i + 4) & 7],
111 t[(16 - i + 5) & 7],
112 t[(16 - i + 6) & 7],
113 ))
114 .wrapping_add(k)
115 .wrapping_add(self.0[i]);
116 t[(16 - i + 3) & 7] = t[(16 - i + 3) & 7].wrapping_add(t[(16 - i + 7) & 7]);
117 t[(16 - i + 7) & 7] = t[(16 - i + 7) & 7]
118 .wrapping_add(Self::Sigma0(t[(16 - i + 0) & 7]))
119 .wrapping_add(Self::Maj(
120 t[(16 - i + 0) & 7],
121 t[(16 - i + 1) & 7],
122 t[(16 - i + 2) & 7],
123 ));
124 }
125
126 fn G(&mut self, state: &mut State, s: usize) {
127 const ROUND_CONSTANTS: [u32; 64] = [
128 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
129 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
130 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
131 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
132 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
133 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
134 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
135 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
136 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
137 0xc67178f2,
138 ];
139 let rc = &ROUND_CONSTANTS[s * 16..];
140 self.F(state, 0, rc[0]);
141 self.F(state, 1, rc[1]);
142 self.F(state, 2, rc[2]);
143 self.F(state, 3, rc[3]);
144 self.F(state, 4, rc[4]);
145 self.F(state, 5, rc[5]);
146 self.F(state, 6, rc[6]);
147 self.F(state, 7, rc[7]);
148 self.F(state, 8, rc[8]);
149 self.F(state, 9, rc[9]);
150 self.F(state, 10, rc[10]);
151 self.F(state, 11, rc[11]);
152 self.F(state, 12, rc[12]);
153 self.F(state, 13, rc[13]);
154 self.F(state, 14, rc[14]);
155 self.F(state, 15, rc[15]);
156 }
157}
158
159impl State {
160 fn new() -> Self {
161 const IV: [u8; 32] = [
162 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f,
163 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab,
164 0x5b, 0xe0, 0xcd, 0x19,
165 ];
166 let mut t = [0u32; 8];
167 for (i, e) in t.iter_mut().enumerate() {
168 *e = load_be(&IV, i * 4)
169 }
170 State(t)
171 }
172
173 #[inline(always)]
174 fn add(&mut self, x: &State) {
175 let sx = &mut self.0;
176 let ex = &x.0;
177 sx[0] = sx[0].wrapping_add(ex[0]);
178 sx[1] = sx[1].wrapping_add(ex[1]);
179 sx[2] = sx[2].wrapping_add(ex[2]);
180 sx[3] = sx[3].wrapping_add(ex[3]);
181 sx[4] = sx[4].wrapping_add(ex[4]);
182 sx[5] = sx[5].wrapping_add(ex[5]);
183 sx[6] = sx[6].wrapping_add(ex[6]);
184 sx[7] = sx[7].wrapping_add(ex[7]);
185 }
186
187 fn store(&self, out: &mut [u8]) {
188 for (i, &e) in self.0.iter().enumerate() {
189 store_be(out, i * 4, e);
190 }
191 }
192
193 fn blocks(&mut self, mut input: &[u8]) -> usize {
194 let mut t = *self;
195 let mut inlen = input.len();
196 while inlen >= 64 {
197 let mut w = W::new(input);
198 w.G(&mut t, 0);
199 w.expand();
200 w.G(&mut t, 1);
201 w.expand();
202 w.G(&mut t, 2);
203 w.expand();
204 w.G(&mut t, 3);
205 t.add(self);
206 self.0 = t.0;
207 input = &input[64..];
208 inlen -= 64;
209 }
210 inlen
211 }
212}
213
214#[derive(Copy, Clone)]
215pub struct Hash {
216 state: State,
217 w: [u8; 64],
218 r: usize,
219 len: usize,
220}
221
222impl Hash {
223 pub fn new() -> Hash {
224 Hash {
225 state: State::new(),
226 r: 0,
227 w: [0u8; 64],
228 len: 0,
229 }
230 }
231
232 fn _update(&mut self, input: impl AsRef<[u8]>) {
233 let input = input.as_ref();
234 let mut n = input.len();
235 self.len += n;
236 let av = 64 - self.r;
237 let tc = ::core::cmp::min(n, av);
238 self.w[self.r..self.r + tc].copy_from_slice(&input[0..tc]);
239 self.r += tc;
240 n -= tc;
241 let pos = tc;
242 if self.r == 64 {
243 self.state.blocks(&self.w);
244 self.r = 0;
245 }
246 if self.r == 0 && n > 0 {
247 let rb = self.state.blocks(&input[pos..]);
248 if rb > 0 {
249 self.w[..rb].copy_from_slice(&input[pos + n - rb..]);
250 self.r = rb;
251 }
252 }
253 }
254
255 pub fn update(&mut self, input: impl AsRef<[u8]>) {
257 self._update(input)
258 }
259
260 pub fn finalize(mut self) -> [u8; 32] {
262 let mut padded = [0u8; 128];
263 padded[..self.r].copy_from_slice(&self.w[..self.r]);
264 padded[self.r] = 0x80;
265 let r = if self.r < 56 { 64 } else { 128 };
266 let bits = self.len * 8;
267 for i in 0..8 {
268 padded[r - 8 + i] = (bits as u64 >> (56 - i * 8)) as u8;
269 }
270 self.state.blocks(&padded[..r]);
271 let mut out = [0u8; 32];
272 self.state.store(&mut out);
273 out
274 }
275
276 pub fn hash(input: &[u8]) -> [u8; 32] {
278 let mut h = Hash::new();
279 h.update(input);
280 h.finalize()
281 }
282}
283
284impl Default for Hash {
285 fn default() -> Self {
286 Self::new()
287 }
288}
289
290#[derive(Clone)]
291pub struct HMAC {
292 ih: Hash,
293 padded: [u8; 64],
294}
295
296impl HMAC {
297 pub fn mac(input: impl AsRef<[u8]>, k: impl AsRef<[u8]>) -> [u8; 32] {
299 let input = input.as_ref();
300 let k = k.as_ref();
301 let mut hk = [0u8; 32];
302 let k2 = if k.len() > 64 {
303 hk.copy_from_slice(&Hash::hash(k));
304 &hk
305 } else {
306 k
307 };
308 let mut padded = [0x36; 64];
309 for (p, &k) in padded.iter_mut().zip(k2.iter()) {
310 *p ^= k;
311 }
312 let mut ih = Hash::new();
313 ih.update(&padded[..]);
314 ih.update(input);
315
316 for p in padded.iter_mut() {
317 *p ^= 0x6a;
318 }
319 let mut oh = Hash::new();
320 oh.update(&padded[..]);
321 oh.update(ih.finalize());
322 oh.finalize()
323 }
324
325 pub fn new(k: impl AsRef<[u8]>) -> HMAC {
326 let k = k.as_ref();
327 let mut hk = [0u8; 32];
328 let k2 = if k.len() > 64 {
329 hk.copy_from_slice(&Hash::hash(k));
330 &hk
331 } else {
332 k
333 };
334 let mut padded = [0x36; 64];
335 for (p, &k) in padded.iter_mut().zip(k2.iter()) {
336 *p ^= k;
337 }
338 let mut ih = Hash::new();
339 ih.update(&padded[..]);
340 HMAC { ih, padded }
341 }
342
343 pub fn update(&mut self, input: impl AsRef<[u8]>) {
345 self.ih.update(input);
346 }
347
348 pub fn finalize(mut self) -> [u8; 32] {
350 for p in self.padded.iter_mut() {
351 *p ^= 0x6a;
352 }
353 let mut oh = Hash::new();
354 oh.update(&self.padded[..]);
355 oh.update(self.ih.finalize());
356 oh.finalize()
357 }
358}
359
360pub struct HKDF;
361
362impl HKDF {
363 pub fn extract(salt: impl AsRef<[u8]>, ikm: impl AsRef<[u8]>) -> [u8; 32] {
364 HMAC::mac(ikm, salt)
365 }
366
367 pub fn expand(out: &mut [u8], prk: impl AsRef<[u8]>, info: impl AsRef<[u8]>) {
368 let info = info.as_ref();
369 let mut counter: u8 = 1;
370 assert!(out.len() < 0xff * 32);
371 let mut i: usize = 0;
372 while i < out.len() {
373 let mut hmac = HMAC::new(&prk);
374 if i != 0 {
375 hmac.update(&out[i - 32..][..32]);
376 }
377 hmac.update(info);
378 hmac.update([counter]);
379 let left = core::cmp::min(32, out.len() - i);
380 out[i..][..left].copy_from_slice(&hmac.finalize()[..left]);
381 counter += 1;
382 i += 32;
383 }
384 }
385}
386
387#[cfg(feature = "traits010")]
389pub type WrappedHash = digest010::core_api::CoreWrapper<Hash>;
390
391#[cfg(feature = "traits010")]
392mod digest_trait010 {
393 use core::fmt;
394
395 use digest010::{
396 block_buffer::Eager,
397 const_oid::{AssociatedOid, ObjectIdentifier},
398 consts::{U32, U64},
399 core_api::{
400 AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore,
401 OutputSizeUser, Reset, UpdateCore,
402 },
403 FixedOutput, FixedOutputReset, HashMarker, Output, Update,
404 };
405
406 use super::Hash;
407
408 impl AssociatedOid for Hash {
409 const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.1");
410 }
411
412 impl AlgorithmName for Hash {
413 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
414 f.write_str("Sha256")
415 }
416 }
417
418 impl HashMarker for Hash {}
419
420 impl BufferKindUser for Hash {
421 type BufferKind = Eager;
422 }
423
424 impl BlockSizeUser for Hash {
425 type BlockSize = U64;
426 }
427
428 impl OutputSizeUser for Hash {
429 type OutputSize = U32;
430 }
431
432 impl UpdateCore for Hash {
433 #[inline]
434 fn update_blocks(&mut self, blocks: &[Block<Self>]) {
435 for block in blocks {
436 self._update(block);
437 }
438 }
439 }
440
441 impl Update for Hash {
442 #[inline]
443 fn update(&mut self, data: &[u8]) {
444 self._update(data);
445 }
446 }
447
448 impl FixedOutputCore for Hash {
449 fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
450 self._update(buffer.get_data());
451 self.finalize_into(out);
452 }
453 }
454
455 impl FixedOutput for Hash {
456 fn finalize_into(self, out: &mut Output<Self>) {
457 let h = self.finalize();
458 out.copy_from_slice(&h);
459 }
460 }
461
462 impl Reset for Hash {
463 fn reset(&mut self) {
464 *self = Self::new()
465 }
466 }
467
468 impl FixedOutputReset for Hash {
469 fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
470 self.finalize_into(out);
471 self.reset();
472 }
473 }
474}
475
476#[cfg(feature = "traits09")]
477mod digest_trait09 {
478 use digest09::consts::{U32, U64};
479 use digest09::{BlockInput, FixedOutputDirty, Output, Reset, Update};
480
481 use super::Hash;
482
483 impl BlockInput for Hash {
484 type BlockSize = U64;
485 }
486
487 impl Update for Hash {
488 fn update(&mut self, input: impl AsRef<[u8]>) {
489 self._update(input)
490 }
491 }
492
493 impl FixedOutputDirty for Hash {
494 type OutputSize = U32;
495
496 fn finalize_into_dirty(&mut self, out: &mut Output<Self>) {
497 let h = self.finalize();
498 out.copy_from_slice(&h);
499 }
500 }
501
502 impl Reset for Hash {
503 fn reset(&mut self) {
504 *self = Self::new()
505 }
506 }
507}
508
509#[test]
510fn main() {
511 let h = HMAC::mac([], [0u8; 32]);
512 assert_eq!(
513 &h[..],
514 &[
515 182, 19, 103, 154, 8, 20, 217, 236, 119, 47, 149, 215, 120, 195, 95, 197, 255, 22, 151,
516 196, 147, 113, 86, 83, 198, 199, 18, 20, 66, 146, 197, 173
517 ]
518 );
519
520 let h = HMAC::mac([42u8; 69], []);
521 assert_eq!(
522 &h[..],
523 &[
524 225, 88, 35, 8, 78, 185, 165, 6, 235, 124, 28, 250, 112, 124, 159, 119, 159, 88, 184,
525 61, 7, 37, 166, 229, 71, 154, 83, 153, 151, 181, 182, 72
526 ]
527 );
528
529 let h = HMAC::mac([69u8; 250], [42u8; 50]);
530 assert_eq!(
531 &h[..],
532 &[
533 112, 156, 120, 216, 86, 25, 79, 210, 155, 193, 32, 120, 116, 134, 237, 14, 198, 1, 64,
534 41, 124, 196, 103, 91, 109, 216, 36, 133, 4, 234, 218, 228
535 ]
536 );
537
538 let mut s = HMAC::new([42u8; 50]);
539 s.update([69u8; 150]);
540 s.update([69u8; 100]);
541 let h = s.finalize();
542 assert_eq!(
543 &h[..],
544 &[
545 112, 156, 120, 216, 86, 25, 79, 210, 155, 193, 32, 120, 116, 134, 237, 14, 198, 1, 64,
546 41, 124, 196, 103, 91, 109, 216, 36, 133, 4, 234, 218, 228
547 ]
548 );
549
550 let ikm = [0x0bu8; 22];
551 let salt = [
552 0x00u8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
553 ];
554 let context = [0xf0u8, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9];
555 let prk = HKDF::extract(salt, ikm);
556 let mut k = [0u8; 40];
557 HKDF::expand(&mut k, prk, context);
558 assert_eq!(
559 &k[..],
560 &[
561 60, 178, 95, 37, 250, 172, 213, 122, 144, 67, 79, 100, 208, 54, 47, 42, 45, 45, 10,
562 144, 207, 26, 90, 76, 93, 176, 45, 86, 236, 196, 197, 191, 52, 0, 114, 8, 213, 184,
563 135, 24
564 ]
565 );
566}