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..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 @@ -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 @@ -73,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 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/README.md b/cbc-mac/README.md index 80ca418..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 @@ -45,7 +52,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 diff --git a/cbc-mac/src/lib.rs b/cbc-mac/src/lib.rs index 40a2ef5..0d189fd 100644 --- a/cbc-mac/src/lib.rs +++ b/cbc-mac/src/lib.rs @@ -1,36 +1,11 @@ -//! [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" )] #![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..f99f34a 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 the [`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..c0f1168 100644 --- a/hmac/README.md +++ b/hmac/README.md @@ -7,21 +7,92 @@ ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -Pure Rust implementation of the [Hash-based Message Authentication Code (HMAC)][1]. +Generic implementation of [Hash-based Message Authentication Code (HMAC)][1]. -[Documentation][docs-link] +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. -## Minimum Supported Rust Version +This crate provides four HMAC implementations: [`Hmac`], [`HmacReset`], +[`SimpleHmac`], and [`SimpleHmacReset`]. -Rust **1.81** or higher. +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. they will not work with the BLAKE2 family of hash functions). -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. +On the other hand, [`SimpleHmac`] and [`SimpleHmacReset`] are a bit less +efficient, but work with all hash functions which implement +the [`Digest`] trait. -## SemVer Policy +[`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. -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above +## Examples + +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`]. + +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, 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 @@ -47,10 +118,24 @@ 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`]: 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 +[`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 430945c..0fba87d 100644 --- a/hmac/src/lib.rs +++ b/hmac/src/lib.rs @@ -1,93 +1,16 @@ -//! 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. -//! +// Overwrite intra-crate links //! [`Reset`]: digest::Reset +//! [`Digest`]: digest::Digest //! [`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 +//! [`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( 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..dcb617b 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`] 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};