/rust/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.23.22/src/crypto/hmac.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use alloc::boxed::Box; |
2 | | |
3 | | use zeroize::Zeroize; |
4 | | |
5 | | /// A concrete HMAC implementation, for a single cryptographic hash function. |
6 | | /// |
7 | | /// You should have one object that implements this trait for HMAC-SHA256, another |
8 | | /// for HMAC-SHA384, etc. |
9 | | pub trait Hmac: Send + Sync { |
10 | | /// Prepare to use `key` as a HMAC key. |
11 | | fn with_key(&self, key: &[u8]) -> Box<dyn Key>; |
12 | | |
13 | | /// Give the length of the underlying hash function. In RFC2104 terminology this is `L`. |
14 | | fn hash_output_len(&self) -> usize; |
15 | | |
16 | | /// Return `true` if this is backed by a FIPS-approved implementation. |
17 | 0 | fn fips(&self) -> bool { |
18 | 0 | false |
19 | 0 | } |
20 | | } |
21 | | |
22 | | /// A HMAC tag, stored as a value. |
23 | | #[derive(Clone)] |
24 | | pub struct Tag { |
25 | | buf: [u8; Self::MAX_LEN], |
26 | | used: usize, |
27 | | } |
28 | | |
29 | | impl Tag { |
30 | | /// Build a tag by copying a byte slice. |
31 | | /// |
32 | | /// The slice can be up to [`Tag::MAX_LEN`] bytes in length. |
33 | 0 | pub fn new(bytes: &[u8]) -> Self { |
34 | 0 | let mut tag = Self { |
35 | 0 | buf: [0u8; Self::MAX_LEN], |
36 | 0 | used: bytes.len(), |
37 | 0 | }; |
38 | 0 | tag.buf[..bytes.len()].copy_from_slice(bytes); |
39 | 0 | tag |
40 | 0 | } |
41 | | |
42 | | /// Maximum supported HMAC tag size: supports up to SHA512. |
43 | | pub const MAX_LEN: usize = 64; |
44 | | } |
45 | | |
46 | | impl Drop for Tag { |
47 | 0 | fn drop(&mut self) { |
48 | 0 | self.buf.zeroize(); |
49 | 0 | } |
50 | | } |
51 | | |
52 | | impl AsRef<[u8]> for Tag { |
53 | 0 | fn as_ref(&self) -> &[u8] { |
54 | 0 | &self.buf[..self.used] |
55 | 0 | } |
56 | | } |
57 | | |
58 | | /// A HMAC key that is ready for use. |
59 | | /// |
60 | | /// The algorithm used is implicit in the `Hmac` object that produced the key. |
61 | | pub trait Key: Send + Sync { |
62 | | /// Calculates a tag over `data` -- a slice of byte slices. |
63 | 0 | fn sign(&self, data: &[&[u8]]) -> Tag { |
64 | 0 | self.sign_concat(&[], data, &[]) |
65 | 0 | } |
66 | | |
67 | | /// Calculates a tag over the concatenation of `first`, the items in `middle`, and `last`. |
68 | | fn sign_concat(&self, first: &[u8], middle: &[&[u8]], last: &[u8]) -> Tag; |
69 | | |
70 | | /// Returns the length of the tag returned by a computation using |
71 | | /// this key. |
72 | | fn tag_len(&self) -> usize; |
73 | | } |