diff --git a/Cargo.lock b/Cargo.lock index b5d40916d1a9f..86c1bfda3aa6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1908,6 +1908,15 @@ name = "hex" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "hkdf" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hmac" version = "0.7.1" @@ -2413,7 +2422,7 @@ dependencies = [ "ed25519-dalek 1.0.0-pre.4 (git+https://github.com/novifinancial/ed25519-dalek.git?branch=fiat3)", "ed25519-dalek 1.0.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hkdf 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "libra-canonical-serialization 0.1.0", "libra-crypto-derive 0.1.0", "libra-nibble 0.1.0", @@ -6796,6 +6805,7 @@ dependencies = [ "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" "checksum hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" +"checksum hkdf 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe1149865383e4526a43aee8495f9a325f0b806c63ce6427d06336a590abbbc9" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hmac 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" "checksum http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" diff --git a/crypto/crypto/Cargo.toml b/crypto/crypto/Cargo.toml index 8de040dc05d28..5a74d53701236 100644 --- a/crypto/crypto/Cargo.toml +++ b/crypto/crypto/Cargo.toml @@ -18,7 +18,7 @@ digest = "0.9.0" vanilla-ed25519-dalek = { version = "1.0.0-pre.4", package = 'ed25519-dalek', optional = true } ed25519-dalek = { git = "https://github.com/novifinancial/ed25519-dalek.git", branch = "fiat3", default-features = false, features = ["std", "fiat_u64_backend", "serde"], optional = true } hex = "0.4.2" -hmac = "0.8.1" +hkdf = "0.9.0" once_cell = "1.4.0" mirai-annotations = "1.9.1" proptest = { version = "0.10.0", optional = true } diff --git a/crypto/crypto/src/hkdf.rs b/crypto/crypto/src/hkdf.rs index 1189290118051..d83d4acbc49b8 100644 --- a/crypto/crypto/src/hkdf.rs +++ b/crypto/crypto/src/hkdf.rs @@ -76,12 +76,11 @@ //! ``` use digest::{ - generic_array::{self, ArrayLength, GenericArray}, + generic_array::{self, ArrayLength}, BlockInput, FixedOutput, Reset, Update, }; -use generic_array::typenum::{IsGreaterOrEqual, True, Unsigned, U32}; -use hmac::{Hmac, Mac, NewMac}; +use generic_array::typenum::{IsGreaterOrEqual, True, U32}; use std::marker::PhantomData; use thiserror::Error; @@ -111,46 +110,25 @@ where { /// The RFC5869 HKDF-Extract operation. pub fn extract(salt: Option<&[u8]>, ikm: &[u8]) -> Result, HkdfError> { - let mut hmac = match salt { - Some(s) => Hmac::::new_varkey(s).map_err(|_| HkdfError::MACKeyError)?, - None => Hmac::::new(&Default::default()), - }; - - hmac.update(ikm); - - Ok(hmac.finalize().into_bytes().to_vec()) + let (arr, _hkdf) = hkdf::Hkdf::::extract(salt, ikm); + Ok(arr.to_vec()) } /// The RFC5869 HKDF-Expand operation. pub fn expand(prk: &[u8], info: Option<&[u8]>, length: usize) -> Result, HkdfError> { - let hmac_output_bytes = D::OutputSize::to_usize(); - if prk.len() < hmac_output_bytes { - return Err(HkdfError::WrongPseudorandomKeyError); - } - // According to RFC5869, MAX_OUTPUT_LENGTH <= 255 * HashLen. - // We specifically exclude zero size as well. - if length == 0 || length > hmac_output_bytes * 255 { + // According to RFC5869, MAX_OUTPUT_LENGTH <= 255 * HashLen — which is + // checked below. + // We specifically exclude a zero size length as well. + if length == 0 { return Err(HkdfError::InvalidOutputLengthError); } - let mut okm = vec![0u8; length]; - let mut prev: Option::OutputSize>> = None; - let mut hmac = Hmac::::new_varkey(prk).map_err(|_| HkdfError::MACKeyError)?; - - for (blocknum, okm_block) in okm.chunks_mut(hmac_output_bytes).enumerate() { - if let Some(ref prev) = prev { - hmac.update(prev) - } - if let Some(_info) = info { - hmac.update(_info); - } - hmac.update(&[blocknum as u8 + 1]); - - let output = hmac.finalize_reset().into_bytes(); - okm_block.copy_from_slice(&output[..okm_block.len()]); - - prev = Some(output); - } + let hkdf = + hkdf::Hkdf::::from_prk(prk).map_err(|_| HkdfError::WrongPseudorandomKeyError)?; + let mut okm = vec![0u8; length]; + hkdf.expand(info.unwrap_or_else(|| &[]), &mut okm) + // length > D::OutputSize::to_usize() * 255 + .map_err(|_| HkdfError::InvalidOutputLengthError)?; Ok(okm) }