From f3cfa94a8168295ffc286b767af5203f104add7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 15:53:57 +0300 Subject: [PATCH 1/9] Use `#![doc = include_str!("../README.md")]` in all crates --- belt-mac/src/lib.rs | 2 +- cbc-mac/src/lib.rs | 2 +- cmac/README.md | 45 ++++++++++++++---- cmac/src/lib.rs | 42 +---------------- hmac/README.md | 107 +++++++++++++++++++++++++++++++++++------- hmac/src/lib.rs | 90 +---------------------------------- pmac/README.md | 43 +++++++++++++---- pmac/src/lib.rs | 42 +---------------- retail-mac/README.md | 32 +++++++++---- retail-mac/src/lib.rs | 36 +------------- 10 files changed, 189 insertions(+), 252 deletions(-) diff --git a/belt-mac/src/lib.rs b/belt-mac/src/lib.rs index 9cfb035..df7e98b 100644 --- a/belt-mac/src/lib.rs +++ b/belt-mac/src/lib.rs @@ -4,8 +4,8 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" )] -#![forbid(unsafe_code)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![forbid(unsafe_code)] #![warn(missing_docs)] pub use digest::{self, KeyInit, Mac}; diff --git a/cbc-mac/src/lib.rs b/cbc-mac/src/lib.rs index 40a2ef5..c87708e 100644 --- a/cbc-mac/src/lib.rs +++ b/cbc-mac/src/lib.rs @@ -30,7 +30,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" )] #![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![deny(unsafe_code)] +#![forbid(unsafe_code)] #![warn(missing_docs)] pub use digest::{self, KeyInit, Mac}; diff --git a/cmac/README.md b/cmac/README.md index 5101e25..b5cf79d 100644 --- a/cmac/README.md +++ b/cmac/README.md @@ -7,21 +7,45 @@ ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -Pure Rust implementation of the [Cipher-based Message Authentication Code (CMAC)][1]. +Generic implementation of [Cipher-based Message Authentication Code (CMAC)][1], +otherwise known as OMAC1. -[Documentation][docs-link] +## Examples +We will use AES-128 block cipher from [`aes`] crate. -## Minimum Supported Rust Version +To get the authentication code: -Rust **1.81** or higher. +```rust +use aes::Aes128; +use cmac::{digest::KeyInit, Cmac, Mac}; -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. +// Create `Mac` trait implementation, namely CMAC-AES128 +let mut mac = Cmac::::new_from_slice(b"very secret key.").unwrap(); +mac.update(b"input message"); -## SemVer Policy +// `result` has type `Output` which is a thin wrapper around array of +// bytes for providing constant time equality check +let result = mac.finalize(); +// To get underlying array use the `into_bytes` method, but be careful, +// since incorrect use of the tag value may permit timing attacks which +// defeat the security provided by the `Output` wrapper +let tag_bytes = result.into_bytes(); +``` -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above +To verify the message: + +```rust +use aes::Aes128; +use cmac::{digest::KeyInit, Cmac, Mac}; + +let mut mac = Cmac::::new_from_slice(b"very secret key.").unwrap(); + +mac.update(b"input message"); + +# let tag_bytes = mac.clone().finalize().into_bytes(); +// `verify` will return `Ok(())` if tag is correct, `Err(MacError)` otherwise +mac.verify(&tag_bytes).unwrap(); +``` ## License @@ -45,7 +69,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/cmac/badge.svg [docs-link]: https://docs.rs/cmac/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs [build-image]: https://github.com/RustCrypto/MACs/workflows/cmac/badge.svg?branch=master&event=push @@ -54,3 +78,4 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) [1]: https://en.wikipedia.org/wiki/One-key_MAC +[`aes`]: https://docs.rs/aes diff --git a/cmac/src/lib.rs b/cmac/src/lib.rs index e55bfbe..635f5ff 100644 --- a/cmac/src/lib.rs +++ b/cmac/src/lib.rs @@ -1,45 +1,5 @@ -//! Generic implementation of [Cipher-based Message Authentication Code (CMAC)][1], -//! otherwise known as OMAC1. -//! -//! # Examples -//! We will use AES-128 block cipher from [aes](https://docs.rs/aes) crate. -//! -//! To get the authentication code: -//! -//! ```rust -//! use aes::Aes128; -//! use cmac::{digest::KeyInit, Cmac, Mac}; -//! -//! // Create `Mac` trait implementation, namely CMAC-AES128 -//! let mut mac = Cmac::::new_from_slice(b"very secret key.").unwrap(); -//! mac.update(b"input message"); -//! -//! // `result` has type `Output` which is a thin wrapper around array of -//! // bytes for providing constant time equality check -//! let result = mac.finalize(); -//! // To get underlying array use the `into_bytes` method, but be careful, -//! // since incorrect use of the tag value may permit timing attacks which -//! // defeat the security provided by the `Output` wrapper -//! let tag_bytes = result.into_bytes(); -//! ``` -//! -//! To verify the message: -//! -//! ```rust -//! # use aes::Aes128; -//! # use cmac::{digest::KeyInit, Cmac, Mac}; -//! let mut mac = Cmac::::new_from_slice(b"very secret key.").unwrap(); -//! -//! mac.update(b"input message"); -//! -//! # let tag_bytes = mac.clone().finalize().into_bytes(); -//! // `verify` will return `Ok(())` if tag is correct, `Err(MacError)` otherwise -//! mac.verify(&tag_bytes).unwrap(); -//! ``` -//! -//! [1]: https://en.wikipedia.org/wiki/One-key_MAC - #![no_std] +#![doc = include_str!("../README.md")] #![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" diff --git a/hmac/README.md b/hmac/README.md index 855b062..0b3c6b9 100644 --- a/hmac/README.md +++ b/hmac/README.md @@ -7,21 +7,89 @@ ![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.81** 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 +Generic implementation of [Hash-based Message Authentication Code (HMAC)][1]. + +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 four HMAC implementations: [`Hmac`], [`HmacReset`], +[`SimpleHmac`], and [`SimpleHmacReset`]. + +The first two types are buffered wrappers around block-level +[`block_api::HmacCore`] and [`block_api::HmacResetCore`] types respectively. +Internally they uses efficient state representation, but work 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`] and [`SimpleHmacReset`] are a bit less +efficient, but work with all hash functions which implement +the [`Digest`][digest::Digest] trait. + +[`Hmac`] and [`SimpleHmac`] do not support resetting MAC state (i.e. they +do not implement the [`Reset`] and [`FixedOutputReset`] traits). Use +[`HmacReset`] or [`SimpleHmacReset`] if you want to reuse MAC state. + +## 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, KeyInit, 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, KeyInit, 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. ## License @@ -47,10 +115,17 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/MACs/actions/workflows/hmac.yml/badge.svg [build-link]: https://github.com/RustCrypto/MACs/actions/workflows/hmac.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-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 +[`digest`]: https://docs.rs/digest +[`sha2`]: https://docs.rs/sha2 +[`RustCrypto/hashes`]: https://github.com/RustCrypto/hashes + +[//]: # (intra-crate links) +[`Reset`]: digest::Reset +[`FixedOutputReset`]: digest::FixedOutputReset diff --git a/hmac/src/lib.rs b/hmac/src/lib.rs index 430945c..c800f19 100644 --- a/hmac/src/lib.rs +++ b/hmac/src/lib.rs @@ -1,93 +1,5 @@ -//! 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 four HMAC implementations: [`Hmac`], [`HmacReset`], -//! [`SimpleHmac`], and [`SimpleHmacReset`]. -//! -//! The first two types are buffered wrappers around block-level -//! [`block_api::HmacCore`] and [`block_api::HmacResetCore`] types respectively. -//! Internally they uses efficient state representation, but work 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`] and [`SimpleHmacReset`] are a bit less -//! efficient, but work with all hash functions which implement -//! the [`Digest`][digest::Digest] trait. -//! -//! [`Hmac`] and [`SimpleHmac`] do not support resetting MAC state (i.e. they -//! do not implement the [`Reset`] and [`FixedOutputReset`] traits). Use -//! [`HmacReset`] or [`SimpleHmacReset`] if you want to reuse MAC state. -//! -//! [`Reset`]: digest::Reset -//! [`FixedOutputReset`]: digest::FixedOutputReset -//! -//! # 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, KeyInit, 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, KeyInit, 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 = include_str!("../README.md")] #![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" diff --git a/pmac/README.md b/pmac/README.md index 85a78ce..574855a 100644 --- a/pmac/README.md +++ b/pmac/README.md @@ -7,21 +7,43 @@ ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -Pure Rust implementation of the [Parallel Message Authentication Code (PMAC)][1]. +Generic implementation of [Parallelizable Message Authentication Code (PMAC)][1]. -[Documentation][docs-link] +## Examples +We will use AES-128 block cipher from the [`aes`](https://docs.rs/aes) crate. -## Minimum Supported Rust Version +To get authentication code: -Rust **1.81** or higher. +```rust +use aes::Aes128; +use pmac::{digest::KeyInit, Pmac, Mac}; -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. +// Create `Mac` trait implementation, namely PMAC-AES128 +let mut mac = Pmac::::new_from_slice(b"very secret key.").unwrap(); +mac.update(b"input message"); -## SemVer Policy +// `result` has type `Output` 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` method, but be careful, since +// incorrect use of the tag value may permit timing attacks which defeat +// the security provided by the `Output` wrapper +let tag_bytes = result.into_bytes(); +``` -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above +To verify the message: + +```rust +# use aes::Aes128; +# use pmac::{digest::KeyInit, Pmac, Mac}; +let mut mac = Pmac::::new_from_slice(b"very secret key.").unwrap(); + +mac.update(b"input message"); + +# let tag_bytes = mac.clone().finalize().into_bytes(); +// `verify` will return `Ok(())` if tag is correct, `Err(MacError)` otherwise +mac.verify(&tag_bytes).unwrap(); +``` ## License @@ -45,7 +67,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/pmac/badge.svg [docs-link]: https://docs.rs/pmac/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs [build-image]: https://github.com/RustCrypto/MACs/workflows/pmac/badge.svg?branch=master&event=push @@ -54,3 +76,4 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) [1]: https://en.wikipedia.org/wiki/PMAC_(cryptography) +`aes`: https://docs.rs/aes diff --git a/pmac/src/lib.rs b/pmac/src/lib.rs index a3fb675..535bbdb 100644 --- a/pmac/src/lib.rs +++ b/pmac/src/lib.rs @@ -1,45 +1,5 @@ -//! Generic implementation of [Parallelizable Message Authentication Code (PMAC)][1], -//! otherwise known as OMAC1. -//! -//! # Examples -//! We will use AES-128 block cipher from the [aes](https://docs.rs/aes) crate. -//! -//! To get authentication code: -//! -//! ```rust -//! use aes::Aes128; -//! use pmac::{digest::KeyInit, Pmac, Mac}; -//! -//! // Create `Mac` trait implementation, namely PMAC-AES128 -//! let mut mac = Pmac::::new_from_slice(b"very secret key.").unwrap(); -//! mac.update(b"input message"); -//! -//! // `result` has type `Output` 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` method, but be careful, since -//! // incorrect use of the tag value may permit timing attacks which defeat -//! // the security provided by the `Output` wrapper -//! let tag_bytes = result.into_bytes(); -//! ``` -//! -//! To verify the message: -//! -//! ```rust -//! # use aes::Aes128; -//! # use pmac::{digest::KeyInit, Pmac, Mac}; -//! let mut mac = Pmac::::new_from_slice(b"very secret key.").unwrap(); -//! -//! mac.update(b"input message"); -//! -//! # let tag_bytes = mac.clone().finalize().into_bytes(); -//! // `verify` will return `Ok(())` if tag is correct, `Err(MacError)` otherwise -//! mac.verify(&tag_bytes).unwrap(); -//! ``` -//! -//! [1]: https://en.wikipedia.org/wiki/PMAC_(cryptography) - #![no_std] +#![doc = include_str!("../README.md")] #![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" diff --git a/retail-mac/README.md b/retail-mac/README.md index fcb28c4..9944e66 100644 --- a/retail-mac/README.md +++ b/retail-mac/README.md @@ -10,19 +10,32 @@ Pure Rust implementation of the [Retail Message Authentication Code][Retail MAC], also known as ISO/IEC 9797-1 MAC algorithm 3. -[Documentation][docs-link] +**WARNING!** The algorithm has known weaknesses in case of variable-length +messages. See the Wikipedia article for [CBC-MAC] for more information. -## Minimum Supported Rust Version +## Examples -Rust **1.81** or higher. +```rust +use retail_mac::{digest::KeyInit, RetailMac, Mac}; +use des::Des; +use hex_literal::hex; -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. +type RetailMacDes = RetailMac; -## SemVer Policy +// test from ISO/IEC 9797-1:2011 section B.4 +// K and K' are concatenated: +let key = hex!("0123456789ABCDEFFEDCBA9876543210"); -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above +let mut mac = RetailMacDes::new_from_slice(&key).unwrap(); +mac.update(b"Now is the time for all "); +let correct = hex!("A1C72E74EA3FA9B6"); +mac.verify_slice(&correct).unwrap(); + +let mut mac2 = RetailMacDes::new_from_slice(&key).unwrap(); +mac2.update(b"Now is the time for it"); +let correct2 = hex!("2E2B1428CC78254F"); +mac2.verify_slice(&correct2).unwrap(); +``` ## License @@ -46,7 +59,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/retail-mac/badge.svg [docs-link]: https://docs.rs/retail-mac/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs [build-image]: https://github.com/RustCrypto/MACs/actions/workflows/retail-mac.yml/badge.svg @@ -55,3 +68,4 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) [Retail MAC]: https://en.wikipedia.org/wiki/ISO/IEC_9797-1#MAC_algorithm_3 +[CBC-MAC]: https://en.wikipedia.org/wiki/CBC-MAC#Security_with_fixed_and_variable-length_messages diff --git a/retail-mac/src/lib.rs b/retail-mac/src/lib.rs index 4cf1cb0..7a45791 100644 --- a/retail-mac/src/lib.rs +++ b/retail-mac/src/lib.rs @@ -1,43 +1,11 @@ -//! [Retail Message Authentication Code (Retail MAC)][Retail MAC] -//! implemented in pure Rust and generic over block cipher. -//! -//! **WARNING!** The algorithm has known weaknesses in case of variable-length -//! messages. See the Wikipedia article for [CBC-MAC] for more information. -//! -//! # Examples -//! -//! ``` -//! use retail_mac::{digest::KeyInit, RetailMac, Mac}; -//! use des::Des; -//! use hex_literal::hex; -//! -//! type RetailMacDes = RetailMac; -//! -//! // test from ISO/IEC 9797-1:2011 section B.4 -//! // K and K' are concatenated: -//! let key = hex!("0123456789ABCDEFFEDCBA9876543210"); -//! -//! let mut mac = RetailMacDes::new_from_slice(&key).unwrap(); -//! mac.update(b"Now is the time for all "); -//! let correct = hex!("A1C72E74EA3FA9B6"); -//! mac.verify_slice(&correct).unwrap(); -//! -//! let mut mac2 = RetailMacDes::new_from_slice(&key).unwrap(); -//! mac2.update(b"Now is the time for it"); -//! let correct2 = hex!("2E2B1428CC78254F"); -//! mac2.verify_slice(&correct2).unwrap(); -//! ``` -//! -//! [Retail MAC]: https://en.wikipedia.org/wiki/ISO/IEC_9797-1#MAC_algorithm_3 -//! [CBC-MAC]: https://en.wikipedia.org/wiki/CBC-MAC#Security_with_fixed_and_variable-length_messages - #![no_std] +#![doc = include_str!("../README.md")] #![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" )] #![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![deny(unsafe_code)] +#![forbid(unsafe_code)] #![warn(missing_docs)] pub use digest::{self, Key, KeyInit, Mac}; From feee183f65c1a907af6265960630990f7835e201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 15:55:27 +0300 Subject: [PATCH 2/9] Fix MSRV badges --- README.md | 2 +- belt-mac/README.md | 14 +------------- cbc-mac/README.md | 2 +- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 31a6a0e..7a86a01 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/MACs/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/MACs -[msrv-1.85]: https://img.shields.io/badge/rustc-1.85.0+-blue.svg +[msrv-1.85]: https://img.shields.io/badge/rustc-1.85+-blue.svg [//]: # (crates) diff --git a/belt-mac/README.md b/belt-mac/README.md index c7d9649..7ec3956 100644 --- a/belt-mac/README.md +++ b/belt-mac/README.md @@ -31,18 +31,6 @@ mac.update(b"input message"); mac.verify(&tag_bytes).unwrap(); ``` -## Minimum Supported Rust Version - -Rust **1.81** 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: @@ -65,7 +53,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/belt-mac/badge.svg [docs-link]: https://docs.rs/belt-mac/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs [build-image]: https://github.com/RustCrypto/MACs/workflows/belt-mac/badge.svg?branch=master&event=push diff --git a/cbc-mac/README.md b/cbc-mac/README.md index 80ca418..2c93e40 100644 --- a/cbc-mac/README.md +++ b/cbc-mac/README.md @@ -45,7 +45,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/cbc-mac/badge.svg [docs-link]: https://docs.rs/cbc-mac/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs [build-image]: https://github.com/RustCrypto/MACs/workflows/cbc-mac/badge.svg?branch=master&event=push From dc2581b19af67555b309e2d60e367cb9835c7804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 15:56:46 +0300 Subject: [PATCH 3/9] Fix belt-mac link --- belt-mac/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/belt-mac/README.md b/belt-mac/README.md index 7ec3956..141650b 100644 --- a/belt-mac/README.md +++ b/belt-mac/README.md @@ -7,7 +7,7 @@ ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -Pure Rust implementation of [`belt-mac`]. +Pure Rust implementation of [`belt-mac`][1]. # Example ```rust @@ -61,4 +61,4 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) -[belt-mac]: https://apmi.bsu.by/assets/files/std/belt-spec371.pdf +[1]: https://apmi.bsu.by/assets/files/std/belt-spec371.pdf From 727a4f9d1d86c610d7a1094d90673234e913ceef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 15:58:30 +0300 Subject: [PATCH 4/9] fix cbc-mac --- cbc-mac/README.md | 27 +++++++++++++++++---------- cbc-mac/src/lib.rs | 27 +-------------------------- 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/cbc-mac/README.md b/cbc-mac/README.md index 2c93e40..5942e13 100644 --- a/cbc-mac/README.md +++ b/cbc-mac/README.md @@ -7,21 +7,28 @@ ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -Pure Rust implementation of the [Cipher Block Chaining Message Authentication Code (CBC-MAC)][CBC-MAC]. +Generic implementation of [Cipher Block Chaining Message Authentication Code (CBC-MAC)][CBC-MAC]. -[Documentation][docs-link] +**WARNING!** The algorithm has known weaknesses in case of variable-length +messages. See the linked Wikipedia article for more information. -## Minimum Supported Rust Version +## Examples -Rust **1.81** or higher. +```rust +use cbc_mac::{digest::KeyInit, CbcMac, Mac}; +use des::Des; +use hex_literal::hex; -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. +// CBC-MAC with the DES block cipher is equivalent to DAA +type Daa = CbcMac; -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above +// test from FIPS 113 +let key = hex!("0123456789ABCDEF"); +let mut mac = Daa::new_from_slice(&key).unwrap(); +mac.update(b"7654321 Now is the time for "); +let correct = hex!("F1D30F6849312CA4"); +mac.verify_slice(&correct).unwrap(); +``` ## License diff --git a/cbc-mac/src/lib.rs b/cbc-mac/src/lib.rs index c87708e..0d189fd 100644 --- a/cbc-mac/src/lib.rs +++ b/cbc-mac/src/lib.rs @@ -1,30 +1,5 @@ -//! [Cipher Block Chaining Message Authentication Code (CBC-MAC)][CBC-MAC] -//! implemented in pure Rust and generic over block cipher. -//! -//! **WARNING!** The algorithm has known weaknesses in case of variable-length -//! messages. See the linked Wikipedia article for more information. -//! -//! # Examples -//! -//! ``` -//! use cbc_mac::{digest::KeyInit, CbcMac, Mac}; -//! use des::Des; -//! use hex_literal::hex; -//! -//! // CBC-MAC with the DES block cipher is equivalent to DAA -//! type Daa = CbcMac; -//! -//! // test from FIPS 113 -//! let key = hex!("0123456789ABCDEF"); -//! let mut mac = Daa::new_from_slice(&key).unwrap(); -//! mac.update(b"7654321 Now is the time for "); -//! let correct = hex!("F1D30F6849312CA4"); -//! mac.verify_slice(&correct).unwrap(); -//! ``` -//! -//! [CBC-MAC]: https://en.wikipedia.org/wiki/CBC-MAC - #![no_std] +#![doc = include_str!("../README.md")] #![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" From 59edeaade25bec37b0edb2f70722493aee46ba74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 16:00:19 +0300 Subject: [PATCH 5/9] tweak docs --- cmac/README.md | 2 +- pmac/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmac/README.md b/cmac/README.md index b5cf79d..f99f34a 100644 --- a/cmac/README.md +++ b/cmac/README.md @@ -11,7 +11,7 @@ Generic implementation of [Cipher-based Message Authentication Code (CMAC)][1], otherwise known as OMAC1. ## Examples -We will use AES-128 block cipher from [`aes`] crate. +We will use AES-128 block cipher from the [`aes`] crate. To get the authentication code: diff --git a/pmac/README.md b/pmac/README.md index 574855a..dcb617b 100644 --- a/pmac/README.md +++ b/pmac/README.md @@ -10,7 +10,7 @@ Generic implementation of [Parallelizable Message Authentication Code (PMAC)][1]. ## Examples -We will use AES-128 block cipher from the [`aes`](https://docs.rs/aes) crate. +We will use AES-128 block cipher from the [`aes`] crate. To get authentication code: @@ -76,4 +76,4 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) [1]: https://en.wikipedia.org/wiki/PMAC_(cryptography) -`aes`: https://docs.rs/aes +[`aes`]: https://docs.rs/aes From 9834e8dc48e87997863ba1e4406945b944fa6d05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 16:09:24 +0300 Subject: [PATCH 6/9] fix intra-crate links in hmac --- hmac/README.md | 10 ++++++++-- hmac/src/lib.rs | 10 ++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/hmac/README.md b/hmac/README.md index 0b3c6b9..f9a926a 100644 --- a/hmac/README.md +++ b/hmac/README.md @@ -127,5 +127,11 @@ dual licensed as above, without any additional terms or conditions. [`RustCrypto/hashes`]: https://github.com/RustCrypto/hashes [//]: # (intra-crate links) -[`Reset`]: digest::Reset -[`FixedOutputReset`]: digest::FixedOutputReset +[`Reset`]: https://docs.rs/digest/latest/digest/trait.Reset.html +[`FixedOutputReset`]: https://docs.rs/digest/latest/digest/trait.FixedOutputReset.html +[`Hmac`]: https://docs.rs/hmac/latest/hmac/struct.Hmac.html +[`HmacReset`]: https://docs.rs/hmac/latest/hmac/struct.HmacReset.html +[`SimpleHmac`]: https://docs.rs/hmac/latest/hmac/struct.SimpleHmac.html +[`SimpleHmacReset`]: https://docs.rs/hmac/latest/hmac/struct.SimpleHmacReset.html +[`block_api::HmacCore`]: https://docs.rs/hmac/latest/hmac/block_api/struct.HmacCore.html +[`block_api::HmacResetCore`]: https://docs.rs/hmac/latest/hmac/block_api/struct.HmacResetCore.html diff --git a/hmac/src/lib.rs b/hmac/src/lib.rs index c800f19..51a50d4 100644 --- a/hmac/src/lib.rs +++ b/hmac/src/lib.rs @@ -1,3 +1,13 @@ +// Overwrite intra-crate links +//! [`Reset`]: digest::Reset +//! [`FixedOutputReset`]: digest::FixedOutputReset +//! [`Hmac`]: Hmac +//! [`HmacReset`]: HmacReset +//! [`SimpleHmac`]: SimpleHmac +//! [`SimpleHmacReset`]: SimpleHmacReset +//! [`block_api::HmacCore`]: block_api::HmacCore +//! [`block_api::HmacResetCore`]: block_api::HmacResetCore + #![no_std] #![doc = include_str!("../README.md")] #![doc( From 05e61bdc60ff16a0c1b4f6e55faa2f0407b33f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 16:10:30 +0300 Subject: [PATCH 7/9] Fix Digest link --- hmac/README.md | 3 ++- hmac/src/lib.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hmac/README.md b/hmac/README.md index f9a926a..fda3b93 100644 --- a/hmac/README.md +++ b/hmac/README.md @@ -24,7 +24,7 @@ hash functions which expose block-level API and consume blocks eagerly On the other hand, [`SimpleHmac`] and [`SimpleHmacReset`] are a bit less efficient, but work with all hash functions which implement -the [`Digest`][digest::Digest] trait. +the [`Digest`] trait. [`Hmac`] and [`SimpleHmac`] do not support resetting MAC state (i.e. they do not implement the [`Reset`] and [`FixedOutputReset`] traits). Use @@ -128,6 +128,7 @@ dual licensed as above, without any additional terms or conditions. [//]: # (intra-crate links) [`Reset`]: https://docs.rs/digest/latest/digest/trait.Reset.html +[`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html [`FixedOutputReset`]: https://docs.rs/digest/latest/digest/trait.FixedOutputReset.html [`Hmac`]: https://docs.rs/hmac/latest/hmac/struct.Hmac.html [`HmacReset`]: https://docs.rs/hmac/latest/hmac/struct.HmacReset.html diff --git a/hmac/src/lib.rs b/hmac/src/lib.rs index 51a50d4..0fba87d 100644 --- a/hmac/src/lib.rs +++ b/hmac/src/lib.rs @@ -1,5 +1,6 @@ // Overwrite intra-crate links //! [`Reset`]: digest::Reset +//! [`Digest`]: digest::Digest //! [`FixedOutputReset`]: digest::FixedOutputReset //! [`Hmac`]: Hmac //! [`HmacReset`]: HmacReset From 3b836518328206f515924483c8600968e88d415d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 16:12:54 +0300 Subject: [PATCH 8/9] tweak hmac docs --- hmac/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hmac/README.md b/hmac/README.md index fda3b93..7d662a6 100644 --- a/hmac/README.md +++ b/hmac/README.md @@ -31,7 +31,8 @@ do not implement the [`Reset`] and [`FixedOutputReset`] traits). Use [`HmacReset`] or [`SimpleHmacReset`] if you want to reuse MAC state. ## Examples -Let us demonstrate how to use HMAC using the SHA-256 hash function. +Let us demonstrate how to use HMAC using the SHA-256 hash function +implemented in the [`sha2`] crate. In the following examples [`Hmac`] is interchangeable with [`SimpleHmac`]. @@ -86,9 +87,10 @@ 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 +generic nature of the implementation, we must handle cases when this assumption +does not hold. This is done by truncating hash output to the hash block size if needed. ## License From 674c2787011da54da0306f927572a2b651ce4e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 28 May 2025 16:14:42 +0300 Subject: [PATCH 9/9] tweak docs --- hmac/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hmac/README.md b/hmac/README.md index 7d662a6..c0f1168 100644 --- a/hmac/README.md +++ b/hmac/README.md @@ -20,7 +20,7 @@ The first two types are buffered wrappers around block-level [`block_api::HmacCore`] and [`block_api::HmacResetCore`] types respectively. Internally they uses efficient state representation, but work 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). +(e.g. they will not work with the BLAKE2 family of hash functions). On the other hand, [`SimpleHmac`] and [`SimpleHmacReset`] are a bit less efficient, but work with all hash functions which implement @@ -31,6 +31,7 @@ do not implement the [`Reset`] and [`FixedOutputReset`] traits). Use [`HmacReset`] or [`SimpleHmacReset`] if you want to reuse MAC state. ## Examples + Let us demonstrate how to use HMAC using the SHA-256 hash function implemented in the [`sha2`] crate.