Skip to content

Commit 3356016

Browse files
committed
hkdf crate now has \#![forbit(missing_docs)]
1 parent 09bf94c commit 3356016

2 files changed

Lines changed: 30 additions & 18 deletions

File tree

crypto/hkdf/benches/hkdf_benches.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::hint::black_box;
99

1010
fn bench_hkdf_sha256(c: &mut Criterion) {
1111
let mut data_block = [0_u8; 1024];
12-
let mut output = KeyMaterial256::new();
12+
let mut output = KeyMaterial512::new();
1313
rng::DefaultRNG::default().next_bytes_out(&mut data_block).unwrap();
1414

1515
let key = KeyMaterial256::from_bytes_as_type(&data_block[..32], KeyType::MACKey).unwrap();

crypto/hkdf/src/lib.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,16 @@ use bouncycastle_core::traits::XOF;
212212
// end doc-only imports
213213

214214
/*** Constants ***/
215-
// Slightly hacky, but set this to accommodate the underlying hash primitive with the largest output size.
216-
// Would be better to somehow pull that at compile time from H, but I'm not sure how to do that.
217-
// todo can I delete this?
218-
const HMAC_BLOCK_LEN: usize = 64;
215+
/// The size of the output key material from the HKDF-Extract phase `prk`, in bytes.
216+
/// This has been sized so that the output KeyMaterial has enough capacity to accommodate the
217+
/// underlying hash primitive with the largest output size.
218+
/// If the given hash function has a smaller output size, then the output KeyMaterial will be
219+
/// under-full (ie have a key_len that does not use its full capacity).
220+
/// TODO: This is a dirty dirty hack because correctly sizing the output key
221+
/// really requires the generic_const_exprs feature, which is currently only available on
222+
/// nightly Rust, and not on stable. Once they merge that feature, we will be able to get rid of this
223+
/// and declare `okm: &mut KeyMaterial<H::OUTPUT_LEN>` instead of this hack.
224+
pub const MAX_HMAC_OUTPUT_LEN: usize = 64;
219225

220226
/*** String constants ***/
221227

@@ -382,7 +388,7 @@ impl<H: Hash + HashAlgParams + Default> HKDF<H> {
382388
salt: &impl KeyMaterialTrait,
383389
ikm: &impl KeyMaterialTrait,
384390
) -> Result<impl KeyMaterialTrait, MACError> {
385-
let mut prk = KeyMaterial::<HMAC_BLOCK_LEN>::new();
391+
let mut prk = KeyMaterial::<MAX_HMAC_OUTPUT_LEN>::new();
386392
Self::extract_out(salt, ikm, &mut prk)?;
387393
Ok(prk)
388394
}
@@ -392,7 +398,7 @@ impl<H: Hash + HashAlgParams + Default> HKDF<H> {
392398
pub fn extract_out(
393399
salt: &impl KeyMaterialTrait,
394400
ikm: &impl KeyMaterialTrait,
395-
prk: &mut KeyMaterial<H::OUTPUT_LEN>,
401+
prk: &mut KeyMaterial<MAX_HMAC_OUTPUT_LEN>,
396402
) -> Result<usize, MACError> {
397403
// PRK = HMAC-Hash(salt, IKM)
398404

@@ -474,12 +480,15 @@ impl<H: Hash + HashAlgParams + Default> HKDF<H> {
474480

475481
// Could potentially speed this up by unrolling T(0) and T(1)
476482

477-
// We're gonna have to kludge the prk key type to MACKey to make HMAC happy, but we'll set it back to the original value afterwards.
478-
let prk_as_mac_key =
479-
KeyMaterial::<HMAC_BLOCK_LEN>::from_bytes_as_type(prk.ref_to_bytes(), KeyType::MACKey)?;
483+
// We're gonna have to kludge the prk key type to MACKey to make HMAC happy,
484+
// but we'll set it back to the original value afterwards.
485+
let prk_as_mac_key = KeyMaterial::<MAX_HMAC_OUTPUT_LEN>::from_bytes_as_type(
486+
prk.ref_to_bytes(),
487+
KeyType::MACKey,
488+
)?;
480489

481490
#[allow(non_snake_case)]
482-
let mut T = [0u8; HMAC_BLOCK_LEN];
491+
let mut T = [0u8; MAX_HMAC_OUTPUT_LEN];
483492
let mut t_len: usize = 0;
484493
let mut i = 1u8;
485494

@@ -637,18 +646,18 @@ impl<H: Hash + HashAlgParams + Default> HKDF<H> {
637646

638647
/// Finish the HKDF-Extract phase and produce the output `prk`.
639648
#[allow(non_snake_case)]
640-
pub fn do_extract_final(self) -> Result<KeyMaterial<HMAC_BLOCK_LEN>, MACError> {
641-
let mut okm = KeyMaterial::<HMAC_BLOCK_LEN>::new();
642-
self.do_extract_final_out(&mut okm)?;
643-
Ok(okm)
649+
pub fn do_extract_final(self) -> Result<KeyMaterial<MAX_HMAC_OUTPUT_LEN>, MACError> {
650+
let mut prk = KeyMaterial::<MAX_HMAC_OUTPUT_LEN>::new();
651+
self.do_extract_final_out(&mut prk)?;
652+
Ok(prk)
644653
}
645654

646655
/// Finish the HKDF-Extract phase and fill the provided `prk`.
647656
/// Note that the provided KeyMaterial must be correctly sized to the HMAC block length.
648657
#[allow(non_snake_case)]
649658
pub fn do_extract_final_out(
650659
self,
651-
okm: &mut KeyMaterial<HMAC_BLOCK_LEN>,
660+
prk: &mut KeyMaterial<MAX_HMAC_OUTPUT_LEN>,
652661
) -> Result<usize, MACError> {
653662
if self.state == HkdfStates::Uninitialized {
654663
return Err(MACError::InvalidState(
@@ -660,7 +669,7 @@ impl<H: Hash + HashAlgParams + Default> HKDF<H> {
660669
let output_key_type = self.entropy.get_output_key_type(); // need to do this above self.hmac.do_final_out, which will consume self.
661670

662671
let mut bytes_written = 0;
663-
key_material::do_hazardous_operations(okm, |okm| {
672+
key_material::do_hazardous_operations(prk, |okm| {
664673
bytes_written = self
665674
.hmac
666675
.unwrap()
@@ -680,6 +689,9 @@ impl<H: Hash + HashAlgParams + Default> HKDF<H> {
680689
)
681690
}
682691
})?;
692+
// By RFC5869, the output size of prk is HashLen denotes the length of the
693+
// hash function output in octets
694+
debug_assert_eq!(prk.key_len(), H::OUTPUT_LEN);
683695
Ok(bytes_written)
684696
}
685697
}
@@ -769,7 +781,7 @@ impl<H: Hash + HashAlgParams + Default> KDF for HKDF<H> {
769781
entropy.credit_entropy(*key);
770782
}
771783
}
772-
let mut prk = KeyMaterial::<HMAC_BLOCK_LEN>::new();
784+
let mut prk = KeyMaterial::<MAX_HMAC_OUTPUT_LEN>::new();
773785
_ = hkdf.do_extract_final_out(&mut prk)?;
774786
let bytes_written =
775787
HKDF::<H>::expand_out(&prk, additional_input, output_key.capacity(), output_key)?;

0 commit comments

Comments
 (0)