From 6a746aef05890b3ee50b5a4a3e07147475fe88f4 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 3 Apr 2023 12:34:52 +0900 Subject: [PATCH] Import hmac 0.12.1 --- .cargo_vcs_info.json | 6 + CHANGELOG.md | 97 +++++++++++ Cargo.toml | 55 ++++++ Cargo.toml.orig | 35 ++++ LICENSE-APACHE | 201 ++++++++++++++++++++++ LICENSE-MIT | 25 +++ README.md | 53 ++++++ src/lib.rs | 131 +++++++++++++++ src/optim.rs | 280 +++++++++++++++++++++++++++++++ src/simple.rs | 106 ++++++++++++ tests/data/md5.blb | Bin 0 -> 245 bytes tests/data/sha224.blb | Bin 0 -> 803 bytes tests/data/sha256.blb | Bin 0 -> 831 bytes tests/data/sha384.blb | Bin 0 -> 943 bytes tests/data/sha512.blb | Bin 0 -> 1062 bytes tests/data/streebog256.blb | Bin 0 -> 84 bytes tests/data/streebog512.blb | Bin 0 -> 117 bytes tests/data/wycheproof-sha1.blb | Bin 0 -> 4875 bytes tests/data/wycheproof-sha256.blb | Bin 0 -> 6153 bytes tests/data/wycheproof-sha384.blb | Bin 0 -> 7857 bytes tests/data/wycheproof-sha512.blb | Bin 0 -> 9648 bytes tests/mod.rs | 88 ++++++++++ 22 files changed, 1077 insertions(+) create mode 100644 .cargo_vcs_info.json create mode 100644 CHANGELOG.md create mode 100644 Cargo.toml create mode 100644 Cargo.toml.orig create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT create mode 100644 README.md create mode 100644 src/lib.rs create mode 100644 src/optim.rs create mode 100644 src/simple.rs create mode 100644 tests/data/md5.blb create mode 100644 tests/data/sha224.blb create mode 100644 tests/data/sha256.blb create mode 100644 tests/data/sha384.blb create mode 100644 tests/data/sha512.blb create mode 100644 tests/data/streebog256.blb create mode 100644 tests/data/streebog512.blb create mode 100644 tests/data/wycheproof-sha1.blb create mode 100644 tests/data/wycheproof-sha256.blb create mode 100644 tests/data/wycheproof-sha384.blb create mode 100644 tests/data/wycheproof-sha512.blb create mode 100644 tests/mod.rs diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json new file mode 100644 index 0000000..36b6de6 --- /dev/null +++ b/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "46797e3b44973a30edb9d7f3a3ebb41810061d90" + }, + "path_in_vcs": "hmac" +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2569cc5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,97 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.12.1 (2022-02-17) +### Fixed +- Minimal versions build ([#108]) + +[#108]: https://github.com/RustCrypto/MACs/pull/108 + +## 0.12.0 (2021-12-07) +### Changed +- Bump `digest` crate dependency to v0.10 and remove `crypto-mac` ([#97]) +- Use a more efficient state representation by using block-level hash API ([#97]) + +### Added +- `SimpleHmac` as a less constrained alternative to `Hmac` ([#97]) + +[#97]: https://github.com/RustCrypto/MACs/pull/97 + +## 0.11.0 (2021-04-29) +### Changed +- Bump `crypto-mac` crate dependency to v0.11 ([#73]) + +[#73]: https://github.com/RustCrypto/MACs/pull/73 + +## 0.10.1 (2020-10-16) +### Added +- Zulip badge ([#64]) + +[#64]: https://github.com/RustCrypto/MACs/pull/64 + +## 0.10.0 (2020-10-16) +### Changed +- Bump `crypto-mac` dependency to v0.10 ([#62]) + +[#62]: https://github.com/RustCrypto/MACs/pull/62 + +## 0.9.0 (2020-08-12) +### Changed +- Bump `crypto-mac` dependency to v0.9 ([#57]) + +### Added +- Implement `io::Write` ([#55]) + +[#55]: https://github.com/RustCrypto/MACs/pull/55 +[#57]: https://github.com/RustCrypto/MACs/pull/57 + +## 0.8.1 (2020-06-24) +### Fixed +- Replace outdated `code` with `into_bytes` in documentation ([#50]) + +[#50]: https://github.com/RustCrypto/MACs/pull/50 + +## 0.8.0 (2020-06-09) +### Changed +- Upgrade to `digest` v0.9 crate release; MSRV 1.41 ([#45]) +- Upgrade `crypto-mac` to v0.8 ([#33]) +- Rename `*result*` to `finalize` ([#38]) +- Upgrade to Rust 2018 edition ([#33]) + +[#45]: https://github.com/RustCrypto/MACs/pull/45 +[#38]: https://github.com/RustCrypto/MACs/pull/38 +[#33]: https://github.com/RustCrypto/MACs/pull/33 + +## 0.7.1 (2019-07-11) + +## 0.7.0 (2018-10-03) + +## 0.6.3 (2018-08-15) + +## 0.6.2 (2018-04-15) + +## 0.6.1 (2018-04-05) + +## 0.6.0 (2018-03-30) + +## 0.5.0 (2017-11-15) + +## 0.4.2 (2017-07-24) + +## 0.4.1 (2017-07-24) + +## 0.4.0 (2017-07-24) + +## 0.3.1 (2017-06-12) + +## 0.1.2 (2017-07-24) + +## 0.1.1 (2017-05-14) + +## 0.1.0 (2017-05-14) + +## 0.0.1 (2016-10-21) diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ca1c001 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,55 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "hmac" +version = "0.12.1" +authors = ["RustCrypto Developers"] +description = "Generic implementation of Hash-based Message Authentication Code (HMAC)" +documentation = "https://docs.rs/hmac" +readme = "README.md" +keywords = ["crypto", "mac", "hmac", "digest"] +categories = ["cryptography", "no-std"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/RustCrypto/MACs" +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +[dependencies.digest] +version = "0.10.3" +features = ["mac"] +[dev-dependencies.digest] +version = "0.10" +features = ["dev"] + +[dev-dependencies.hex-literal] +version = "0.2.2" + +[dev-dependencies.md-5] +version = "0.10" +default-features = false + +[dev-dependencies.sha-1] +version = "0.10" +default-features = false + +[dev-dependencies.sha2] +version = "0.10" +default-features = false + +[dev-dependencies.streebog] +version = "0.10" +default-features = false + +[features] +reset = [] +std = ["digest/std"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig new file mode 100644 index 0000000..d04c7cf --- /dev/null +++ b/Cargo.toml.orig @@ -0,0 +1,35 @@ +[package] +name = "hmac" +version = "0.12.1" # Also update html_root_url in lib.rs when bumping this +description = "Generic implementation of Hash-based Message Authentication Code (HMAC)" +authors = ["RustCrypto Developers"] +license = "MIT OR Apache-2.0" +edition = "2018" +readme = "README.md" +documentation = "https://docs.rs/hmac" +repository = "https://github.com/RustCrypto/MACs" +keywords = ["crypto", "mac", "hmac", "digest"] +categories = ["cryptography", "no-std"] + +# Hack to allow this crate to coexist with 2021 edition crates +[workspace] +members = ["."] + +[dependencies] +digest = { version = "0.10.3", features = ["mac"] } + +[dev-dependencies] +digest = { version = "0.10", features = ["dev"] } +md-5 = { version = "0.10", default-features = false } +sha-1 = { version = "0.10", default-features = false } +sha2 = { version = "0.10", default-features = false } +streebog = { version = "0.10", default-features = false } +hex-literal = "0.2.2" + +[features] +std = ["digest/std"] +reset = [] # Enable ability to reset HMAC instances + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..78173fa --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..8dcb85b --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2017 Artyom Pavlov + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..52d4ef9 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# RustCrypto: HMAC + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] + +Pure Rust implementation of the [Hash-based Message Authentication Code (HMAC)][1]. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/hmac.svg +[crate-link]: https://crates.io/crates/hmac +[docs-image]: https://docs.rs/hmac/badge.svg +[docs-link]: https://docs.rs/hmac/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs + +[//]: # (general links) + +[1]: https://en.wikipedia.org/wiki/HMAC diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..e79c068 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,131 @@ +//! Generic implementation of Hash-based Message Authentication Code (HMAC). +//! +//! To use it you will need a cryptographic hash function implementation which +//! implements the [`digest`] crate traits. You can find compatible crates +//! (e.g. [`sha2`]) in the [`RustCrypto/hashes`] repository. +//! +//! This crate provides two HMAC implementation [`Hmac`] and [`SimpleHmac`]. +//! The first one is a buffered wrapper around block-level [`HmacCore`]. +//! Internally it uses efficient state representation, but works only with +//! hash functions which expose block-level API and consume blocks eagerly +//! (e.g. it will not work with the BLAKE2 family of hash functions). +//! On the other hand, [`SimpleHmac`] is a bit less efficient memory-wise, +//! but works with all hash functions which implement the [`Digest`] trait. +//! +//! # Examples +//! Let us demonstrate how to use HMAC using the SHA-256 hash function. +//! +//! In the following examples [`Hmac`] is interchangeable with [`SimpleHmac`]. +//! +//! To get authentication code: +//! +//! ```rust +//! use sha2::Sha256; +//! use hmac::{Hmac, Mac}; +//! use hex_literal::hex; +//! +//! // Create alias for HMAC-SHA256 +//! type HmacSha256 = Hmac; +//! +//! let mut mac = HmacSha256::new_from_slice(b"my secret and secure key") +//! .expect("HMAC can take key of any size"); +//! mac.update(b"input message"); +//! +//! // `result` has type `CtOutput` which is a thin wrapper around array of +//! // bytes for providing constant time equality check +//! let result = mac.finalize(); +//! // To get underlying array use `into_bytes`, but be careful, since +//! // incorrect use of the code value may permit timing attacks which defeats +//! // the security provided by the `CtOutput` +//! let code_bytes = result.into_bytes(); +//! let expected = hex!(" +//! 97d2a569059bbcd8ead4444ff99071f4 +//! c01d005bcefe0d3567e1be628e5fdcd9 +//! "); +//! assert_eq!(code_bytes[..], expected[..]); +//! ``` +//! +//! To verify the message: +//! +//! ```rust +//! # use sha2::Sha256; +//! # use hmac::{Hmac, Mac}; +//! # use hex_literal::hex; +//! # type HmacSha256 = Hmac; +//! let mut mac = HmacSha256::new_from_slice(b"my secret and secure key") +//! .expect("HMAC can take key of any size"); +//! +//! mac.update(b"input message"); +//! +//! let code_bytes = hex!(" +//! 97d2a569059bbcd8ead4444ff99071f4 +//! c01d005bcefe0d3567e1be628e5fdcd9 +//! "); +//! // `verify_slice` will return `Ok(())` if code is correct, `Err(MacError)` otherwise +//! mac.verify_slice(&code_bytes[..]).unwrap(); +//! ``` +//! +//! # Block and input sizes +//! Usually it is assumed that block size is larger than output size. Due to the +//! generic nature of the implementation, this edge case must be handled as well +//! to remove potential panic. This is done by truncating hash output to the hash +//! block size if needed. +//! +//! [`digest`]: https://docs.rs/digest +//! [`sha2`]: https://docs.rs/sha2 +//! [`RustCrypto/hashes`]: https://github.com/RustCrypto/hashes + +#![no_std] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", + html_root_url = "https://docs.rs/hmac/0.12.1" +)] +#![forbid(unsafe_code)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![warn(missing_docs, rust_2018_idioms)] + +#[cfg(feature = "std")] +extern crate std; + +pub use digest; +pub use digest::Mac; + +use digest::{ + core_api::{Block, BlockSizeUser}, + Digest, +}; + +mod optim; +mod simple; + +pub use optim::{Hmac, HmacCore}; +pub use simple::SimpleHmac; + +const IPAD: u8 = 0x36; +const OPAD: u8 = 0x5C; + +fn get_der_key(key: &[u8]) -> Block { + let mut der_key = Block::::default(); + // The key that HMAC processes must be the same as the block size of the + // underlying hash function. If the provided key is smaller than that, + // we just pad it with zeros. If its larger, we hash it and then pad it + // with zeros. + if key.len() <= der_key.len() { + der_key[..key.len()].copy_from_slice(key); + } else { + let hash = D::digest(key); + // All commonly used hash functions have block size bigger + // than output hash size, but to be extra rigorous we + // handle the potential uncommon cases as well. + // The condition is calcualted at compile time, so this + // branch gets removed from the final binary. + if hash.len() <= der_key.len() { + der_key[..hash.len()].copy_from_slice(&hash); + } else { + let n = der_key.len(); + der_key.copy_from_slice(&hash[..n]); + } + } + der_key +} diff --git a/src/optim.rs b/src/optim.rs new file mode 100644 index 0000000..32d6277 --- /dev/null +++ b/src/optim.rs @@ -0,0 +1,280 @@ +use super::{get_der_key, IPAD, OPAD}; +use core::{fmt, slice}; +#[cfg(feature = "reset")] +use digest::Reset; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreProxy, CoreWrapper, + FixedOutputCore, OutputSizeUser, UpdateCore, + }, + crypto_common::{Key, KeySizeUser}, + generic_array::typenum::{IsLess, Le, NonZero, U256}, + HashMarker, InvalidLength, KeyInit, MacMarker, Output, +}; + +/// Generic HMAC instance. +pub type Hmac = CoreWrapper>; + +/// Generic core HMAC instance, which operates over blocks. +pub struct HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + digest: D::Core, + opad_digest: D::Core, + #[cfg(feature = "reset")] + ipad_digest: D::Core, +} + +impl Clone for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + fn clone(&self) -> Self { + Self { + digest: self.digest.clone(), + opad_digest: self.opad_digest.clone(), + #[cfg(feature = "reset")] + ipad_digest: self.ipad_digest.clone(), + } + } +} + +impl MacMarker for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ +} + +impl BufferKindUser for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + type BufferKind = Eager; +} + +impl KeySizeUser for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + type KeySize = <::Core as BlockSizeUser>::BlockSize; +} + +impl BlockSizeUser for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + type BlockSize = <::Core as BlockSizeUser>::BlockSize; +} + +impl OutputSizeUser for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + type OutputSize = <::Core as OutputSizeUser>::OutputSize; +} + +impl KeyInit for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + #[inline(always)] + fn new(key: &Key) -> Self { + Self::new_from_slice(key.as_slice()).unwrap() + } + + #[inline(always)] + fn new_from_slice(key: &[u8]) -> Result { + let mut buf = get_der_key::>(key); + for b in buf.iter_mut() { + *b ^= IPAD; + } + let mut digest = D::Core::default(); + digest.update_blocks(slice::from_ref(&buf)); + + for b in buf.iter_mut() { + *b ^= IPAD ^ OPAD; + } + + let mut opad_digest = D::Core::default(); + opad_digest.update_blocks(slice::from_ref(&buf)); + + Ok(Self { + #[cfg(feature = "reset")] + ipad_digest: digest.clone(), + opad_digest, + digest, + }) + } +} + +impl UpdateCore for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + #[inline(always)] + fn update_blocks(&mut self, blocks: &[Block]) { + self.digest.update_blocks(blocks); + } +} + +impl FixedOutputCore for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + #[inline(always)] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let mut hash = Output::::default(); + self.digest.finalize_fixed_core(buffer, &mut hash); + // finalize_fixed_core should reset the buffer as well, but + // to be extra safe we reset it explicitly again. + buffer.reset(); + #[cfg(not(feature = "reset"))] + let h = &mut self.opad_digest; + #[cfg(feature = "reset")] + let mut h = self.opad_digest.clone(); + buffer.digest_blocks(&hash, |b| h.update_blocks(b)); + h.finalize_fixed_core(buffer, out); + } +} + +#[cfg(feature = "reset")] +#[cfg_attr(docsrs, doc(cfg(feature = "reset")))] +impl Reset for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + #[inline(always)] + fn reset(&mut self) { + self.digest = self.ipad_digest.clone(); + } +} + +impl AlgorithmName for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + AlgorithmName + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Hmac<")?; + ::write_alg_name(f)?; + f.write_str(">") + } +} + +impl fmt::Debug for HmacCore +where + D: CoreProxy, + D::Core: HashMarker + + AlgorithmName + + UpdateCore + + FixedOutputCore + + BufferKindUser + + Default + + Clone, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("HmacCore<")?; + ::write_alg_name(f)?; + f.write_str("> { ... }") + } +} diff --git a/src/simple.rs b/src/simple.rs new file mode 100644 index 0000000..e28c4c3 --- /dev/null +++ b/src/simple.rs @@ -0,0 +1,106 @@ +use super::{get_der_key, IPAD, OPAD}; +use core::fmt; +use digest::{ + crypto_common::{Block, BlockSizeUser, InvalidLength, Key, KeySizeUser}, + Digest, FixedOutput, KeyInit, MacMarker, Output, OutputSizeUser, Update, +}; +#[cfg(feature = "reset")] +use digest::{FixedOutputReset, Reset}; + +/// Simplified HMAC instance able to operate over hash functions +/// which do not expose block-level API and hash functions which +/// process blocks lazily (e.g. BLAKE2). +#[derive(Clone)] +pub struct SimpleHmac { + digest: D, + opad_key: Block, + #[cfg(feature = "reset")] + ipad_key: Block, +} + +impl KeySizeUser for SimpleHmac { + type KeySize = D::BlockSize; +} + +impl MacMarker for SimpleHmac {} + +impl KeyInit for SimpleHmac { + fn new(key: &Key) -> Self { + Self::new_from_slice(key.as_slice()).unwrap() + } + + #[inline] + fn new_from_slice(key: &[u8]) -> Result { + let der_key = get_der_key::(key); + let mut ipad_key = der_key.clone(); + for b in ipad_key.iter_mut() { + *b ^= IPAD; + } + let mut digest = D::new(); + digest.update(&ipad_key); + + let mut opad_key = der_key; + for b in opad_key.iter_mut() { + *b ^= OPAD; + } + + Ok(Self { + digest, + opad_key, + #[cfg(feature = "reset")] + ipad_key, + }) + } +} + +impl Update for SimpleHmac { + #[inline(always)] + fn update(&mut self, data: &[u8]) { + self.digest.update(data); + } +} + +impl OutputSizeUser for SimpleHmac { + type OutputSize = D::OutputSize; +} + +impl FixedOutput for SimpleHmac { + fn finalize_into(self, out: &mut Output) { + let mut h = D::new(); + h.update(&self.opad_key); + h.update(&self.digest.finalize()); + h.finalize_into(out); + } +} + +impl fmt::Debug for SimpleHmac { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SimpleHmac") + .field("digest", &self.digest) + // TODO: replace with `finish_non_exhaustive` on MSRV + // bump to 1.53 + .field("..", &"..") + .finish() + } +} + +#[cfg(feature = "reset")] +#[cfg_attr(docsrs, doc(cfg(feature = "reset")))] +impl Reset for SimpleHmac { + fn reset(&mut self) { + Reset::reset(&mut self.digest); + self.digest.update(&self.ipad_key); + } +} + +#[cfg(feature = "reset")] +#[cfg_attr(docsrs, doc(cfg(feature = "reset")))] +impl FixedOutputReset for SimpleHmac { + fn finalize_into_reset(&mut self, out: &mut Output) { + let mut h = D::new(); + Update::update(&mut h, &self.opad_key); + Update::update(&mut h, &self.digest.finalize_reset()); + Update::update(&mut self.digest, &self.ipad_key); + Digest::finalize_into(h, out); + } +} diff --git a/tests/data/md5.blb b/tests/data/md5.blb new file mode 100644 index 0000000000000000000000000000000000000000..731a0ae4dd9795d4f216caea146d157ee0b30cc2 GIT binary patch literal 245 zcmZQj;6?)i9+?Uu8L3673X`T3Rhe1rmJ$Ba_d~S%&s+|#)U;HK@{Gh1g_L}S%0z|o z#Jm!PwEQB4y!?`k%)E4ag;JghyQ~dcnP08QGvtchZlSOW4W!&987PG9GYOIv@#(m| zLKWLVj6lkwOVjIw!HJ66n%& Wg$8zZVK=*S&z(HFhdc!zl>z`~H*|~u literal 0 HcmV?d00001 diff --git a/tests/data/sha224.blb b/tests/data/sha224.blb new file mode 100644 index 0000000000000000000000000000000000000000..dabb20b3d4a772516517f0b3899844d8c48fa060 GIT binary patch literal 803 zcmZQ%fDYVN!IKx|s z!z(o{)uKEju|y#yU!gKlp*%6KL?JD|NFgu3BqK8~-QHp`A0ub?vD^DyGx@FR=H>Et z?_0EZUZMv>|Ajag4Q!rIxl1yzsNa0rwBy*pZ~s?j`qpM$N|~Ix;o!H}%!_ZDjb9lt zGBLBTvaxe;a&hzU^6?7@3JHsdiit}|rko`iSmX!>WRx)4tjW^aBfYsPspd`Agd2H( z7Ni0fFEdoYGVxEFiPJVK>Zg6H*s)BcFrGl=4M`CdX znCX^TR9s>)_2q)w(-fwzUAJ$xZa(jxM^|Qk6#8^&ySn|dc0R^NgOH5OVg(>dR44&C zsT6E}qCyVDh7ynsNnjg_K{jLqZAi>Z0jkEKASJORQ4f?xz)JH{Q&Wl+O7azwQWY|Q z&Pq)IvVaL86-a^nQCbWVsZ=Nds`v19bXG{rNzX3=hDxrUg;lF#+M3w;O!gsH#V>50 TyLU=@!RTntBlcBLjhZ literal 0 HcmV?d00001 diff --git a/tests/data/sha256.blb b/tests/data/sha256.blb new file mode 100644 index 0000000000000000000000000000000000000000..6b5b288e1b310da7c0b1f9f5c57c5ce1ea02b887 GIT binary patch literal 831 zcmZQWiiXehHuH4 z#u+m|aagr}__g?H#Siu>J^L@|nrYD*JXnB6NNRD3LU?9LhC)bDXkc`Y?1t3aPC;>UG6l_PLLJq{15|AxPU|WhowqyfsNz6+Ds>Y!p zC9xz?50rMmO7l`vQ;HQz@)eR&6*7QMOHBc?fQcg&NP+xPS_~4YR44(e_waReR!GcA u&o2UoPOhHAY|j77rKjkhR!@%Kb9KW@m;HB=Q~cS5CwJ8c2FF;LJ^}!&!Gz`j literal 0 HcmV?d00001 diff --git a/tests/data/sha384.blb b/tests/data/sha384.blb new file mode 100644 index 0000000000000000000000000000000000000000..d5cddb3124a3f8c872e6e098c0697f08a4b45078 GIT binary patch literal 943 zcmZQI8!KTJ>`Pteou0?Aeh@4oF&$Z0-ru&-tuV2`Gc^a7};;j|6dG0|A zk)3{4+a5A5_E$GzWMXDvWn<^yMC+6cQE@6%&_`OgT$3NU-b5++Ja$+A3+h zI%&fCoaI$B8$CDz80H)eugQ}SxAx0mysLa<`L)V3KNhzgD>?sLg9i)H2uUq2Q3%g0 z$xsL>D$PqyEXmBzOR(B+ayY| zTIOdvc1=oleE($KE5;nKF`>o4_)zdkEJ{x;0!DXYo`O?OesZ>MaAsAif_G}Ag06x` zVsQqT>6TekT$12-j>Dz3(QZP=rDIks(nq)W&-=)zr5(|4b5Wj^+3LtK9=&g?9Sr_8 zO;hRpnEb^vh_TTiBqOs}0f-V6N2dZkOQ%`1Y~Ox*w$i@t=T|Z6Z2Als&Obt zNi0d!1Eo!{(!A8vlwyUFe1)V`g$$rmQ&WH}U}8%JQXs#T7K2186-t2WJ$xOV6%upO z^NWC?m#deMCNADLMV^V*R8C*jum7@6f{Mbw4Lg3%x^r%KlbhVkqsuDJ7(SmVo@HEaF{vWoeNXh1GP_F#)=$zl7imD5n zSzRC2+`F~Hc>A>-%bA$F)&15j{_hg zdoe|=M7<;Oq0yw@MvP3%EUawo9GqO-JiL7T0)j%qBBEmA5|SxrNd^rJ8+N&cnY;F6 zPI$WF=r>uf?@!Ba*8lWw*L|Mf5MU&q3K?7t9~TtIpWVe@QVmOD<^YGymdm z_FQkeCq~VPtw^20*k}-vky)$&M2QL|AkUS89g(Pz193(P$QemsXB2~+kqvZ4VqOYR zH4X(Si6x18pd0{JnwOfIQmjytuaK0gkO6diY6_4AOu?x@3gp?+VvtCsLJ3g4hp(fv zLSjyOei1NybM+b+9#?0T$DXL&wdDTFpLucifA8%r{Lxm_*%teCv97||lP=qsbk^8- gHf`jMdmVcC$vshFx3b^44_p#bPnJ0R>dA@#0GYT0&;S4c literal 0 HcmV?d00001 diff --git a/tests/data/streebog256.blb b/tests/data/streebog256.blb new file mode 100644 index 0000000000000000000000000000000000000000..99d972294164965bf9419fc56433218b5de26b1f GIT binary patch literal 84 zcmV-a0IUB1KmY*(0|W&I2M7rY3k(eo4-gR&6BHE|7Z@2D8yp=TA0PoHy|{P)uOUN0 qMP*}n0RTXus$YHN0@t(CBl4LXjYTv8F*gAUgLO~PuWfwPk}la~G!{t! literal 0 HcmV?d00001 diff --git a/tests/data/streebog512.blb b/tests/data/streebog512.blb new file mode 100644 index 0000000000000000000000000000000000000000..8f0f151fca255a5a7e2657727aa043a7b5835f21 GIT binary patch literal 117 zcmV-*0E+(rKmY*(0|W&I2M7rY3k(eo4-gR&6BHE|7Z@2D8yp=TA0PoHy|{P)uOUN0 zMP*}n0RVsirJJiF?5-KcU%lq#^y&53RGl&KH~HV2kW~QTagsWBJzo_t^6h?>OtS9W XDe0{*I{uTgflqn$01x~FX2MbCJLN0B literal 0 HcmV?d00001 diff --git a/tests/data/wycheproof-sha1.blb b/tests/data/wycheproof-sha1.blb new file mode 100644 index 0000000000000000000000000000000000000000..a4f8f43632d11124cbf16144fd039242070185f0 GIT binary patch literal 4875 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 literal 0 HcmV?d00001 diff --git a/tests/data/wycheproof-sha256.blb b/tests/data/wycheproof-sha256.blb new file mode 100644 index 0000000000000000000000000000000000000000..62f1d3570d4f3ae76580e79070534a08575f8275 GIT binary patch literal 6153 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 b8$-NO;f|OfFYNwB*ONKLecifft2FiT1!u{8 literal 0 HcmV?d00001 diff --git a/tests/data/wycheproof-sha384.blb b/tests/data/wycheproof-sha384.blb new file mode 100644 index 0000000000000000000000000000000000000000..69a787437553300cf439bce35bc32175172fd0d1 GIT binary patch literal 7857 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 P4}u4Sjq{2(aC&1f8tN<= literal 0 HcmV?d00001 diff --git a/tests/data/wycheproof-sha512.blb b/tests/data/wycheproof-sha512.blb new file mode 100644 index 0000000000000000000000000000000000000000..e061fd554b2d1498f59912cfbe7b86b16af051d1 GIT binary patch literal 9648 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%0AMDm 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 +test!(hmac_md5_rfc2104_simple, "md5", SimpleHmac); + +// Test vectors from RFC 4231 +test!(hmac_sha224_rfc4231, "sha224", Hmac); +test!(hmac_sha256_rfc4231, "sha256", Hmac); +test!(hmac_sha384_rfc4231, "sha384", Hmac); +test!(hmac_sha512_rfc4231, "sha512", Hmac); +test!(hmac_sha224_rfc4231_simple, "sha224", SimpleHmac); +test!(hmac_sha256_rfc4231_simple, "sha256", SimpleHmac); +test!(hmac_sha384_rfc4231_simple, "sha384", SimpleHmac); +test!(hmac_sha512_rfc4231_simple, "sha512", SimpleHmac); + +// Test vectors from R 50.1.113-2016: +// https://tc26.ru/standard/rs/Р 50.1.113-2016.pdf +test!(hmac_streebog256, "streebog256", Hmac); +test!(hmac_streebog512, "streebog512", Hmac); +test!( + hmac_streebog256_simple, + "streebog256", + SimpleHmac +); +test!( + hmac_streebog512_simple, + "streebog512", + SimpleHmac +); + +// Tests from Project Wycheproof: +// https://github.com/google/wycheproof +test!( + hmac_sha1_wycheproof, + "wycheproof-sha1", + Hmac, + trunc_left, +); +test!( + hmac_sha256_wycheproof, + "wycheproof-sha256", + Hmac, + trunc_left, +); +test!( + hmac_sha384_wycheproof, + "wycheproof-sha384", + Hmac, + trunc_left, +); +test!( + hmac_sha512_wycheproof, + "wycheproof-sha512", + Hmac, + trunc_left, +); +test!( + hmac_sha1_wycheproof_simple, + "wycheproof-sha1", + SimpleHmac, + trunc_left, +); +test!( + hmac_sha256_wycheproof_simple, + "wycheproof-sha256", + SimpleHmac, + trunc_left, +); +test!( + hmac_sha384_wycheproof_simple, + "wycheproof-sha384", + SimpleHmac, + trunc_left, +); +test!( + hmac_sha512_wycheproof_simple, + "wycheproof-sha512", + SimpleHmac, + trunc_left, +); -- 2.34.1