Skip to content

Commit 1ae5e0a

Browse files
Add reference to spec and TV source. (fmt)
1 parent 767b0c6 commit 1ae5e0a

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

gmac/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
Generic implementation of the [Galois Message Authentication Code (GMAC)][GMAC].
1111

12+
GMAC is defined by NIST [SP 800-38D] as an authentication-only specialization of
13+
GCM (Galois Counter Mode). It is equivalent to GCM encryption with an empty plaintext
14+
and data only provided in the AAD.
15+
1216
**WARNING!** This is a nonce-based MAC and must have a unique nonce for each generation.
1317
This is identical to the issues with nonce-reuse and AES-GCM (which uses GMAC internally).
1418
This also means that it is dangerous to clone an instance of GMAC when generating a MAC.
@@ -94,3 +98,4 @@ dual licensed as above, without any additional terms or conditions.
9498
[RustCrypto]: https://github.com/RustCrypto
9599
[GMAC]: https://en.wikipedia.org/wiki/Galois/Counter_Mode
96100
[`aes`]: https://docs.rs/aes
101+
[SP 800-38D]: https://doi.org/10.6028/NIST.SP.800-38D

gmac/src/lib.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
)]
77
#![cfg_attr(docsrs, feature(doc_cfg))]
88

9-
pub use digest::{self, Mac};
109
pub use aes::cipher::KeyIvInit;
10+
pub use digest::{self, Mac};
1111

1212
use aes::{
1313
Aes128Enc, Aes192Enc, Aes256Enc,
@@ -64,7 +64,6 @@ where
6464
buffer_len: usize,
6565
}
6666

67-
6867
impl<Aes, NonceSize> Gmac<Aes, NonceSize>
6968
where
7069
Aes: GmacCipher,
@@ -115,26 +114,30 @@ where
115114
}
116115

117116
/// Generate a random nonce for use with GMAC.
118-
///
117+
///
119118
/// GMAC accepts a parameter to encryption/decryption called a "nonce"
120119
/// which must be unique every time a MAC is generated and never repeated for the same key.
121120
/// The nonce is often prepended to the tag. The nonce used to produce a given tag must be
122121
/// passed to the verification MAC calculation.
123-
///
122+
///
124123
/// Nonces don’t necessarily have to be random, but it is one strategy which is implemented by this function.
125-
///
124+
///
126125
/// # ⚠️Security Warning
127-
///
126+
///
128127
/// GMAC fails catastrophically if the nonce is ever repeated.
129-
///
128+
///
130129
/// Using random nonces runs the risk of repeating them. The best case for GMAC is with a 12 byte nonce.
131130
/// With a 12-byte (96-bit) nonce, you can safely generate 2^32 (4,294,967,296) random nonces before the risk
132131
/// of repeating one becomes too high.
133132
#[cfg(feature = "rand_core")]
134133
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
135134
#[inline]
136-
pub fn generate_nonce<Rng>(mut rng: Rng) -> Result<GenericArray<u8, NonceSize>, <Rng as TryRng>::Error>
137-
where Rng: TryCryptoRng {
135+
pub fn generate_nonce<Rng>(
136+
mut rng: Rng,
137+
) -> Result<GenericArray<u8, NonceSize>, <Rng as TryRng>::Error>
138+
where
139+
Rng: TryCryptoRng,
140+
{
138141
let mut nonce = GenericArray::<u8, NonceSize>::default();
139142
rng.try_fill_bytes(&mut nonce)?;
140143
Ok(nonce)
@@ -283,4 +286,4 @@ where
283286
Aes: GmacCipher,
284287
NonceSize: generic_array::ArrayLength<u8>,
285288
{
286-
}
289+
}

gmac/tests/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,20 @@ struct GmacTestVector {
1818
pub tag: &'static [u8],
1919
}
2020

21+
// Source for CAVP test vectors: https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES
22+
2123
blobby::parse_into_structs!(
24+
// All CAVP SP 800-38D test vectors for 128 bit keys and empty plaintexts
2225
include_bytes!("data/gmac_aes128.blb");
2326
static GMAC_128_KATS: &[GmacTestVector { key, iv, data, tag}];
2427
);
2528
blobby::parse_into_structs!(
29+
// All CAVP SP 800-38D test vectors for 192 bit keys and empty plaintexts
2630
include_bytes!("data/gmac_aes192.blb");
2731
static GMAC_192_KATS: &[GmacTestVector { key, iv, data, tag}];
2832
);
2933
blobby::parse_into_structs!(
34+
// All CAVP SP 800-38D test vectors for 256 bit keys and empty plaintexts
3035
include_bytes!("data/gmac_aes256.blb");
3136
static GMAC_256_KATS: &[GmacTestVector { key, iv, data, tag}];
3237
);
@@ -56,8 +61,8 @@ fn nonce_generation() {
5661
#[cfg(feature = "rand_core")]
5762
#[test]
5863
fn nonce_generation_16() {
59-
use rand::rngs::SysRng;
6064
use cipher::consts::U16;
65+
use rand::rngs::SysRng;
6166

6267
let fake_key = [0u8; 16];
6368
let nonce = Gmac::<Aes128Enc, U16>::generate_nonce(SysRng).expect("SysRng failed");
@@ -140,7 +145,9 @@ where
140145
)
141146
}
142147
}
143-
if let Err(reason) = initialized_mac_test(mac, tv.data, tv.tag, digest::dev::MacTruncSide::Left) {
148+
if let Err(reason) =
149+
initialized_mac_test(mac, tv.data, tv.tag, digest::dev::MacTruncSide::Left)
150+
{
144151
panic!(
145152
"\n\
146153
Failed test (truncated) {name}#{idx}\n\

0 commit comments

Comments
 (0)