hmac_drbg/
lib.rs

1#![no_std]
2
3use digest::{BlockInput, FixedOutput, Reset, Update};
4use generic_array::{ArrayLength, GenericArray};
5use hmac::{Hmac, Mac, NewMac};
6
7pub struct HmacDRBG<D>
8where
9    D: Update + BlockInput + FixedOutput + Default,
10    D::BlockSize: ArrayLength<u8>,
11    D::OutputSize: ArrayLength<u8>,
12{
13    k: GenericArray<u8, D::OutputSize>,
14    v: GenericArray<u8, D::OutputSize>,
15    count: usize,
16}
17
18impl<D> HmacDRBG<D>
19where
20    D: Update + FixedOutput + BlockInput + Reset + Clone + Default,
21    D::BlockSize: ArrayLength<u8>,
22    D::OutputSize: ArrayLength<u8>,
23{
24    pub fn new(entropy: &[u8], nonce: &[u8], pers: &[u8]) -> Self {
25        let mut k = GenericArray::<u8, D::OutputSize>::default();
26        let mut v = GenericArray::<u8, D::OutputSize>::default();
27
28        for i in 0..k.as_slice().len() {
29            k[i] = 0x0;
30        }
31
32        for i in 0..v.as_slice().len() {
33            v[i] = 0x01;
34        }
35
36        let mut this = Self { k, v, count: 0 };
37
38        this.update(Some(&[entropy, nonce, pers]));
39        this.count = 1;
40
41        this
42    }
43
44    pub fn count(&self) -> usize {
45        self.count
46    }
47
48    pub fn reseed(&mut self, entropy: &[u8], add: Option<&[u8]>) {
49        self.update(Some(&[entropy, add.unwrap_or(&[])]))
50    }
51
52    pub fn generate<T: ArrayLength<u8>>(&mut self, add: Option<&[u8]>) -> GenericArray<u8, T> {
53        let mut result = GenericArray::default();
54        self.generate_to_slice(result.as_mut_slice(), add);
55        result
56    }
57
58    pub fn generate_to_slice(&mut self, result: &mut [u8], add: Option<&[u8]>) {
59        if let Some(add) = add {
60            self.update(Some(&[add]));
61        }
62
63        let mut i = 0;
64        while i < result.len() {
65            let mut vmac = self.hmac();
66            vmac.update(&self.v);
67            self.v = vmac.finalize().into_bytes();
68
69            for j in 0..self.v.len() {
70                result[i + j] = self.v[j];
71            }
72            i += self.v.len();
73        }
74
75        match add {
76            Some(add) => {
77                self.update(Some(&[add]));
78            }
79            None => {
80                self.update(None);
81            }
82        }
83        self.count += 1;
84    }
85
86    fn hmac(&self) -> Hmac<D> {
87        Hmac::new_varkey(&self.k).expect("Smaller and larger key size are handled by default")
88    }
89
90    fn update(&mut self, seeds: Option<&[&[u8]]>) {
91        let mut kmac = self.hmac();
92        kmac.update(&self.v);
93        kmac.update(&[0x00]);
94        if let Some(seeds) = seeds {
95            for seed in seeds {
96                kmac.update(seed);
97            }
98        }
99        self.k = kmac.finalize().into_bytes();
100
101        let mut vmac = self.hmac();
102        vmac.update(&self.v);
103        self.v = vmac.finalize().into_bytes();
104
105        if seeds.is_none() {
106            return;
107        }
108
109        let seeds = seeds.unwrap();
110
111        let mut kmac = self.hmac();
112        kmac.update(&self.v);
113        kmac.update(&[0x01]);
114        for seed in seeds {
115            kmac.update(seed);
116        }
117        self.k = kmac.finalize().into_bytes();
118
119        let mut vmac = self.hmac();
120        vmac.update(&self.v);
121        self.v = vmac.finalize().into_bytes();
122    }
123}