1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use crypto_provider::hkdf::InvalidLength; 16 use hmac::digest::block_buffer::Eager; 17 use hmac::digest::consts::U256; 18 use hmac::digest::core_api::{ 19 BlockSizeUser, BufferKindUser, CoreProxy, FixedOutputCore, UpdateCore, 20 }; 21 use hmac::digest::typenum::{IsLess, Le, NonZero}; 22 use hmac::digest::{HashMarker, OutputSizeUser}; 23 24 /// RustCrypto based hkdf implementation 25 pub struct Hkdf<D>(hkdf::Hkdf<D>) 26 where 27 D: OutputSizeUser, 28 D: CoreProxy, 29 D::Core: HashMarker 30 + UpdateCore 31 + FixedOutputCore 32 + BufferKindUser<BufferKind = Eager> 33 + Default 34 + Clone, 35 <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, 36 Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero; 37 38 impl<D> crypto_provider::hkdf::Hkdf for Hkdf<D> 39 where 40 D: OutputSizeUser, 41 D: CoreProxy, 42 D::Core: HashMarker 43 + UpdateCore 44 + FixedOutputCore 45 + BufferKindUser<BufferKind = Eager> 46 + Default 47 + Clone, 48 <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, 49 Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, 50 { 51 fn new(salt: Option<&[u8]>, ikm: &[u8]) -> Self { 52 Hkdf(hkdf::Hkdf::new(salt, ikm)) 53 } 54 55 fn expand_multi_info( 56 &self, 57 info_components: &[&[u8]], 58 okm: &mut [u8], 59 ) -> Result<(), InvalidLength> { 60 self.0.expand_multi_info(info_components, okm).map_err(|_| InvalidLength) 61 } 62 63 fn expand(&self, info: &[u8], okm: &mut [u8]) -> Result<(), InvalidLength> { 64 self.0.expand(info, okm).map_err(|_| InvalidLength) 65 } 66 } 67 68 #[cfg(test)] 69 mod tests { 70 use crate::RustCrypto; 71 use core::marker::PhantomData; 72 use crypto_provider_test::hkdf::*; 73 74 #[apply(hkdf_test_cases)] 75 fn hkdf_tests(testcase: CryptoProviderTestCase<RustCrypto>) { 76 testcase(PhantomData); 77 } 78 } 79