/rust/registry/src/index.crates.io-6f17d22bba15001f/hmac-0.13.0-pre.4/src/lib.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Generic implementation of Hash-based Message Authentication Code (HMAC). |
2 | | //! |
3 | | //! To use it you will need a cryptographic hash function implementation which |
4 | | //! implements the [`digest`] crate traits. You can find compatible crates |
5 | | //! (e.g. [`sha2`]) in the [`RustCrypto/hashes`] repository. |
6 | | //! |
7 | | //! This crate provides two HMAC implementation [`Hmac`] and [`SimpleHmac`]. |
8 | | //! The first one is a buffered wrapper around block-level [`HmacCore`]. |
9 | | //! Internally it uses efficient state representation, but works only with |
10 | | //! hash functions which expose block-level API and consume blocks eagerly |
11 | | //! (e.g. it will not work with the BLAKE2 family of hash functions). |
12 | | //! On the other hand, [`SimpleHmac`] is a bit less efficient memory-wise, |
13 | | //! but works with all hash functions which implement the [`Digest`] trait. |
14 | | //! |
15 | | //! # Examples |
16 | | //! Let us demonstrate how to use HMAC using the SHA-256 hash function. |
17 | | //! |
18 | | //! In the following examples [`Hmac`] is interchangeable with [`SimpleHmac`]. |
19 | | //! |
20 | | //! To get authentication code: |
21 | | //! |
22 | | //! ```rust |
23 | | //! use sha2::Sha256; |
24 | | //! use hmac::{Hmac, KeyInit, Mac}; |
25 | | //! use hex_literal::hex; |
26 | | //! |
27 | | //! // Create alias for HMAC-SHA256 |
28 | | //! type HmacSha256 = Hmac<Sha256>; |
29 | | //! |
30 | | //! let mut mac = HmacSha256::new_from_slice(b"my secret and secure key") |
31 | | //! .expect("HMAC can take key of any size"); |
32 | | //! mac.update(b"input message"); |
33 | | //! |
34 | | //! // `result` has type `CtOutput` which is a thin wrapper around array of |
35 | | //! // bytes for providing constant time equality check |
36 | | //! let result = mac.finalize(); |
37 | | //! // To get underlying array use `into_bytes`, but be careful, since |
38 | | //! // incorrect use of the code value may permit timing attacks which defeats |
39 | | //! // the security provided by the `CtOutput` |
40 | | //! let code_bytes = result.into_bytes(); |
41 | | //! let expected = hex!(" |
42 | | //! 97d2a569059bbcd8ead4444ff99071f4 |
43 | | //! c01d005bcefe0d3567e1be628e5fdcd9 |
44 | | //! "); |
45 | | //! assert_eq!(code_bytes[..], expected[..]); |
46 | | //! ``` |
47 | | //! |
48 | | //! To verify the message: |
49 | | //! |
50 | | //! ```rust |
51 | | //! # use sha2::Sha256; |
52 | | //! # use hmac::{Hmac, KeyInit, Mac}; |
53 | | //! # use hex_literal::hex; |
54 | | //! # type HmacSha256 = Hmac<Sha256>; |
55 | | //! let mut mac = HmacSha256::new_from_slice(b"my secret and secure key") |
56 | | //! .expect("HMAC can take key of any size"); |
57 | | //! |
58 | | //! mac.update(b"input message"); |
59 | | //! |
60 | | //! let code_bytes = hex!(" |
61 | | //! 97d2a569059bbcd8ead4444ff99071f4 |
62 | | //! c01d005bcefe0d3567e1be628e5fdcd9 |
63 | | //! "); |
64 | | //! // `verify_slice` will return `Ok(())` if code is correct, `Err(MacError)` otherwise |
65 | | //! mac.verify_slice(&code_bytes[..]).unwrap(); |
66 | | //! ``` |
67 | | //! |
68 | | //! # Block and input sizes |
69 | | //! Usually it is assumed that block size is larger than output size. Due to the |
70 | | //! generic nature of the implementation, this edge case must be handled as well |
71 | | //! to remove potential panic. This is done by truncating hash output to the hash |
72 | | //! block size if needed. |
73 | | //! |
74 | | //! # Crate features |
75 | | //! - `std`: enables functionality dependent on `std` (e.g. implementation of |
76 | | //! the [`Error`][std::error::Error] trait for error types) |
77 | | //! - `reset`: enables implementation of the [`Reset`][digest::Reset] trait |
78 | | //! (note that it makes HMAC states bigger) |
79 | | //! |
80 | | //! [`digest`]: https://docs.rs/digest |
81 | | //! [`sha2`]: https://docs.rs/sha2 |
82 | | //! [`RustCrypto/hashes`]: https://github.com/RustCrypto/hashes |
83 | | |
84 | | #![no_std] |
85 | | #![doc( |
86 | | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", |
87 | | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" |
88 | | )] |
89 | | #![forbid(unsafe_code)] |
90 | | #![cfg_attr(docsrs, feature(doc_cfg))] |
91 | | #![warn(missing_docs, rust_2018_idioms)] |
92 | | |
93 | | #[cfg(feature = "std")] |
94 | | extern crate std; |
95 | | |
96 | | pub use digest; |
97 | | pub use digest::{KeyInit, Mac}; |
98 | | |
99 | | use digest::{ |
100 | | core_api::{Block, BlockSizeUser}, |
101 | | Digest, |
102 | | }; |
103 | | |
104 | | mod optim; |
105 | | mod simple; |
106 | | |
107 | | pub use optim::{EagerHash, Hmac, HmacCore}; |
108 | | pub use simple::SimpleHmac; |
109 | | |
110 | | const IPAD: u8 = 0x36; |
111 | | const OPAD: u8 = 0x5C; |
112 | | |
113 | 3.17k | fn get_der_key<D: Digest + BlockSizeUser>(key: &[u8]) -> Block<D> { |
114 | 3.17k | let mut der_key = Block::<D>::default(); |
115 | 3.17k | // The key that HMAC processes must be the same as the block size of the |
116 | 3.17k | // underlying hash function. If the provided key is smaller than that, |
117 | 3.17k | // we just pad it with zeros. If its larger, we hash it and then pad it |
118 | 3.17k | // with zeros. |
119 | 3.17k | if key.len() <= der_key.len() { |
120 | 3.17k | der_key[..key.len()].copy_from_slice(key); |
121 | 3.17k | } else { |
122 | 0 | let hash = D::digest(key); |
123 | 0 | // All commonly used hash functions have block size bigger |
124 | 0 | // than output hash size, but to be extra rigorous we |
125 | 0 | // handle the potential uncommon cases as well. |
126 | 0 | // The condition is calculated at compile time, so this |
127 | 0 | // branch gets removed from the final binary. |
128 | 0 | if hash.len() <= der_key.len() { |
129 | 0 | der_key[..hash.len()].copy_from_slice(&hash); |
130 | 0 | } else { |
131 | 0 | let n = der_key.len(); |
132 | 0 | der_key.copy_from_slice(&hash[..n]); |
133 | 0 | } |
134 | | } |
135 | 3.17k | der_key |
136 | 3.17k | } |