88#![ forbid( unsafe_code) ]
99#![ warn( missing_docs) ]
1010
11- pub use hmac;
12-
13- use core:: fmt;
14- use core:: marker:: PhantomData ;
15- use hmac:: digest:: {
16- Output , OutputSizeUser , array:: typenum:: Unsigned , crypto_common:: AlgorithmName ,
11+ use hmac:: {
12+ Hmac , SimpleHmac ,
13+ digest:: { Output , OutputSizeUser , array:: typenum:: Unsigned } ,
1714} ;
18- use hmac:: { Hmac , SimpleHmac } ;
1915
2016mod errors;
2117mod hmac_impl;
2218
2319pub use errors:: { InvalidLength , InvalidPrkLength } ;
20+ pub use hmac;
2421pub use hmac_impl:: HmacImpl ;
2522
26- /// [`HkdfExtract`] variant which uses [`SimpleHmac`] for underlying HMAC
27- /// implementation.
28- pub type SimpleHkdfExtract < H > = HkdfExtract < H , SimpleHmac < H > > ;
29- /// [`Hkdf`] variant which uses [`SimpleHmac`] for underlying HMAC
30- /// implementation.
31- pub type SimpleHkdf < H > = Hkdf < H , SimpleHmac < H > > ;
32-
33- /// Structure representing the streaming context of an HKDF-Extract operation
34- /// ```rust
35- /// # use hkdf::{Hkdf, HkdfExtract};
36- /// # use sha2::Sha256;
37- /// let mut extract_ctx = HkdfExtract::<Sha256>::new(Some(b"mysalt"));
38- /// extract_ctx.input_ikm(b"hello");
39- /// extract_ctx.input_ikm(b" world");
40- /// let (streamed_res, _) = extract_ctx.finalize();
23+ /// [`GenericHkdfExtract`] variant which uses [`Hmac`] for the underlying HMAC implementation.
24+ pub type HkdfExtract < H > = GenericHkdfExtract < Hmac < H > > ;
25+ /// [`GenericHkdf`] variant which uses [`Hmac`] for the underlying HMAC implementation.
26+ pub type Hkdf < H > = GenericHkdf < Hmac < H > > ;
27+
28+ /// [`GenericHkdfExtract`] variant which uses [`SimpleHmac`] for the underlying HMAC implementation.
29+ pub type SimpleHkdfExtract < H > = GenericHkdfExtract < SimpleHmac < H > > ;
30+ /// [`GenericHkdf`] variant which uses [`SimpleHmac`] for the underlying HMAC implementation.
31+ pub type SimpleHkdf < H > = GenericHkdf < SimpleHmac < H > > ;
32+
33+ /// Structure representing the streaming context of an HKDF-Extract operation.
4134///
42- /// let (oneshot_res, _) = Hkdf::<Sha256>::extract(Some(b"mysalt"), b"hello world");
43- /// assert_eq!(streamed_res, oneshot_res);
44- /// ```
45- #[ derive( Clone ) ]
46- pub struct HkdfExtract < H , I = Hmac < H > >
47- where
48- H : OutputSizeUser ,
49- I : HmacImpl < H > ,
50- {
51- hmac : I ,
52- _pd : PhantomData < H > ,
35+ /// This type is generic over HMAC implementation. Most users should use
36+ /// [`HkdfExtract`] or [`SimpleHkdfExtract`] type aliases.
37+ #[ derive( Clone , Debug ) ]
38+ pub struct GenericHkdfExtract < H : HmacImpl > {
39+ hmac : H ,
5340}
5441
55- impl < H , I > HkdfExtract < H , I >
56- where
57- H : OutputSizeUser ,
58- I : HmacImpl < H > ,
59- {
42+ impl < H : HmacImpl > GenericHkdfExtract < H > {
6043 /// Initiates the HKDF-Extract context with the given optional salt
6144 pub fn new ( salt : Option < & [ u8 ] > ) -> Self {
6245 let default_salt = Output :: < H > :: default ( ) ;
6346 let salt = salt. unwrap_or ( & default_salt) ;
64- Self {
65- hmac : I :: new_from_slice ( salt) ,
66- _pd : PhantomData ,
67- }
47+ let hmac = H :: new_from_slice ( salt) ;
48+ Self { hmac }
6849 }
6950
7051 /// Feeds in additional input key material to the HKDF-Extract context
@@ -74,35 +55,25 @@ where
7455
7556 /// Completes the HKDF-Extract operation, returning both the generated pseudorandom key and
7657 /// `Hkdf` struct for expanding.
77- pub fn finalize ( self ) -> ( Output < H > , Hkdf < H , I > ) {
58+ pub fn finalize ( self ) -> ( Output < H > , GenericHkdf < H > ) {
7859 let prk = self . hmac . finalize ( ) ;
79- let hkdf = Hkdf :: from_prk ( & prk) . expect ( "PRK size is correct" ) ;
60+ let hkdf = GenericHkdf :: < H > :: from_prk ( & prk) . expect ( "PRK size is correct" ) ;
8061 ( prk, hkdf)
8162 }
8263}
8364
84- impl < H , I > fmt:: Debug for HkdfExtract < H , I >
85- where
86- H : OutputSizeUser ,
87- I : HmacImpl < H > + AlgorithmName ,
88- {
89- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
90- f. write_str ( "HkdfExtract<" ) ?;
91- <I as AlgorithmName >:: write_alg_name ( f) ?;
92- f. write_str ( "> { ... }" )
93- }
94- }
95-
9665/// Structure representing the HKDF, capable of HKDF-Expand and HKDF-Extract operations.
9766/// Recommendations for the correct usage of the parameters can be found in the
9867/// [crate root](index.html#usage).
99- #[ derive( Clone ) ]
100- pub struct Hkdf < H : OutputSizeUser , I : HmacImpl < H > = Hmac < H > > {
101- hmac : I ,
102- _pd : PhantomData < H > ,
68+ ///
69+ /// This type is generic over HMAC implementation. Most users should use
70+ /// [`Hkdf`] or [`SimpleHkdf`] type aliases.
71+ #[ derive( Clone , Debug ) ]
72+ pub struct GenericHkdf < H : HmacImpl > {
73+ hmac : H ,
10374}
10475
105- impl < H : OutputSizeUser , I : HmacImpl < H > > Hkdf < H , I > {
76+ impl < H : HmacImpl > GenericHkdf < H > {
10677 /// Convenience method for [`extract`][Hkdf::extract] when the generated
10778 /// pseudorandom key can be ignored and only HKDF-Expand operation is needed. This is the most
10879 /// common constructor.
@@ -114,20 +85,19 @@ impl<H: OutputSizeUser, I: HmacImpl<H>> Hkdf<H, I> {
11485 /// Create `Hkdf` from an already cryptographically strong pseudorandom key
11586 /// as per section 3.3 from RFC5869.
11687 pub fn from_prk ( prk : & [ u8 ] ) -> Result < Self , InvalidPrkLength > {
117- // section 2.3 specifies that prk must be "at least HashLen octets"
118- if prk. len ( ) < <H as OutputSizeUser >:: OutputSize :: to_usize ( ) {
88+ // section 2.3 specifies that `prk` must be "at least HashLen octets"
89+ let hash_len = <H as OutputSizeUser >:: OutputSize :: to_usize ( ) ;
90+ if prk. len ( ) < hash_len {
11991 return Err ( InvalidPrkLength ) ;
12092 }
121- Ok ( Self {
122- hmac : I :: new_from_slice ( prk) ,
123- _pd : PhantomData ,
124- } )
93+ let hmac = H :: new_from_slice ( prk) ;
94+ Ok ( Self { hmac } )
12595 }
12696
12797 /// The RFC5869 HKDF-Extract operation returning both the generated
12898 /// pseudorandom key and `Hkdf` struct for expanding.
12999 pub fn extract ( salt : Option < & [ u8 ] > , ikm : & [ u8 ] ) -> ( Output < H > , Self ) {
130- let mut extract_ctx = HkdfExtract :: new ( salt) ;
100+ let mut extract_ctx = GenericHkdfExtract :: < H > :: new ( salt) ;
131101 extract_ctx. input_ikm ( ikm) ;
132102 extract_ctx. finalize ( )
133103 }
@@ -180,16 +150,3 @@ impl<H: OutputSizeUser, I: HmacImpl<H>> Hkdf<H, I> {
180150 self . expand_multi_info ( & [ info] , okm)
181151 }
182152}
183-
184- impl < H , I > fmt:: Debug for Hkdf < H , I >
185- where
186- H : OutputSizeUser ,
187- I : HmacImpl < H > ,
188- I : AlgorithmName ,
189- {
190- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
191- f. write_str ( "Hkdf<" ) ?;
192- <I as AlgorithmName >:: write_alg_name ( f) ?;
193- f. write_str ( "> { ... }" )
194- }
195- }
0 commit comments