9393 /// Derives `key` from `kin` and other parameters.
9494 fn derive (
9595 & self ,
96- kin : & GenericArray < u8 , Prf :: KeySize > ,
96+ //kin: &GenericArray<u8, Prf::KeySize>,
97+ kin : & [ u8 ] ,
9798 use_l : bool ,
9899 use_separator : bool ,
99100 label : & [ u8 ] ,
@@ -116,23 +117,42 @@ where
116117
117118 let mut ki = None ;
118119 self . input_iv ( & mut ki) ;
120+ let mut a = {
121+ let mut h = <Prf as Mac >:: new_from_slice ( kin) . unwrap ( ) ;
122+ h. update ( label) ;
123+ h. update ( & [ 0 ] ) ;
124+ h. update ( context) ;
125+ h. finalize ( ) . into_bytes ( )
126+ } ;
119127
120128 for counter in 1 ..=n {
121- let mut h = <Prf as Mac >:: new ( kin) ;
129+ if counter > 1 {
130+ a = {
131+ let mut h = <Prf as Mac >:: new_from_slice ( kin) . unwrap ( ) ;
132+ h. update ( a. as_slice ( ) ) ;
133+ h. finalize ( ) . into_bytes ( )
134+ } ;
135+ }
136+
137+ let mut h = <Prf as Mac >:: new_from_slice ( kin) . unwrap ( ) ;
122138
123139 if Self :: FEEDBACK_KI {
124140 if let Some ( ki) = ki {
125141 h. update ( ki. as_slice ( ) ) ;
126142 }
127143 }
128144
129- // counter encoded as big endian u32
130- // Type parameter R encodes how large the value is to be (either U8, U16, U24, or U32)
131- //
132- // counter = 1u32 ([0, 0, 0, 1])
133- // \-------/
134- // R = u24
135- h. update ( & counter. to_be_bytes ( ) [ ( 4 - R :: USIZE / 8 ) ..] ) ;
145+ if Self :: DOUBLE_PIPELINE {
146+ h. update ( a. as_slice ( ) ) ;
147+ } else {
148+ // counter encoded as big endian u32
149+ // Type parameter R encodes how large the value is to be (either U8, U16, U24, or U32)
150+ //
151+ // counter = 1u32 ([0, 0, 0, 1])
152+ // \-------/
153+ // R = u24
154+ h. update ( & counter. to_be_bytes ( ) [ ( 4 - R :: USIZE / 8 ) ..] ) ;
155+ }
136156
137157 // Fixed input data
138158 h. update ( label) ;
@@ -166,6 +186,8 @@ where
166186
167187 /// Whether the KI should be reinjected every round.
168188 const FEEDBACK_KI : bool = false ;
189+
190+ const DOUBLE_PIPELINE : bool = false ;
169191}
170192
171193pub struct Counter < Prf , K , R = U32 > {
@@ -231,10 +253,41 @@ where
231253 const FEEDBACK_KI : bool = true ;
232254}
233255
256+ pub struct DoublePipeline < Prf , K , R = U32 >
257+ where
258+ Prf : Mac ,
259+ {
260+ _marker : PhantomData < ( Prf , K , R ) > ,
261+ }
262+
263+ impl < Prf , K , R > Default for DoublePipeline < Prf , K , R >
264+ where
265+ Prf : Mac ,
266+ {
267+ fn default ( ) -> Self {
268+ Self {
269+ _marker : PhantomData ,
270+ }
271+ }
272+ }
273+
274+ impl < Prf , K , R > Kbkdf < Prf , K , R > for DoublePipeline < Prf , K , R >
275+ where
276+ Prf : Mac + KeyInit ,
277+ K : KeySizeUser ,
278+ K :: KeySize : ArrayLength < u8 > + Mul < U8 > ,
279+ <K :: KeySize as Mul < U8 > >:: Output : Unsigned ,
280+ Prf :: OutputSize : ArrayLength < u8 > + Mul < U8 > ,
281+ <Prf :: OutputSize as Mul < U8 > >:: Output : Unsigned ,
282+ R : sealed:: R ,
283+ {
284+ const DOUBLE_PIPELINE : bool = true ;
285+ }
286+
234287#[ cfg( test) ]
235288mod tests {
236- use super :: { Counter , Feedback , GenericArray , Kbkdf } ;
237- use digest:: consts:: * ;
289+ use super :: { Counter , DoublePipeline , Feedback , GenericArray , Kbkdf } ;
290+ use digest:: { consts:: * , crypto_common :: KeySizeUser } ;
238291 use hex_literal:: hex;
239292
240293 #[ derive( Debug ) ]
@@ -293,6 +346,44 @@ mod tests {
293346 } ,
294347 ] ;
295348
349+ #[ test]
350+ fn test_static_values_counter ( ) {
351+ type HmacSha256 = hmac:: Hmac < sha2:: Sha256 > ;
352+ type HmacSha512 = hmac:: Hmac < sha2:: Sha512 > ;
353+
354+ let counter = Counter :: < HmacSha256 , HmacSha512 > :: default ( ) ;
355+ for ( v, i) in KNOWN_VALUES_COUNTER_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
356+ assert_eq ! (
357+ counter. derive( v. key, v. use_l, v. use_separator, v. label, v. context, ) ,
358+ Ok ( GenericArray :: <_, _>:: from_slice( v. expected) . clone( ) ) ,
359+ "key derivation failed for (index: {i}):\n {v:x?}"
360+ ) ;
361+ }
362+ }
363+
364+ #[ test]
365+ fn test_counter_kbkdfvs ( ) {
366+ type HmacSha256 = hmac:: Hmac < sha2:: Sha256 > ;
367+ struct MockOutput ;
368+
369+ impl KeySizeUser for MockOutput {
370+ type KeySize = U32 ;
371+ }
372+
373+ let counter = Counter :: < HmacSha256 , MockOutput > :: default ( ) ;
374+ // KDFCTR_gen.txt count 15
375+ assert_eq ! (
376+ counter. derive(
377+ & hex!( "43eef6d824fd820405626ab9b6d79f1fd04e126ab8e17729e3afc7cb5af794f8" ) ,
378+ false ,
379+ false ,
380+ & hex!( "5e269b5a7bdedcc3e875e2725693a257fc60011af7dcd68a3358507fe29b0659ca66951daa05a15032033650bc58a27840f8fbe9f4088b9030738f68" ) ,
381+ & [ ] ,
382+ ) ,
383+ Ok ( GenericArray :: <_, _>:: from_slice( & hex!( "f0a339ecbcae6add1afb27da3ba40a1320c6427a58afb9dc366b219b7eb29ecf" ) ) . clone( ) ) ,
384+ ) ;
385+ }
386+
296387 static KNOWN_VALUES_FEEDBACK_HMAC_SHA256 : & [ KnownValue ] = & [
297388 KnownValue {
298389 iv : Some ( b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ) ,
@@ -339,43 +430,51 @@ mod tests {
339430 ] ;
340431
341432 #[ test]
342- fn test_static_values_counter ( ) {
433+ fn test_static_values_feedback ( ) {
343434 type HmacSha256 = hmac:: Hmac < sha2:: Sha256 > ;
344435 type HmacSha512 = hmac:: Hmac < sha2:: Sha512 > ;
345436
346- let counter = Counter :: < HmacSha256 , HmacSha512 > :: default ( ) ;
347- for ( v, i) in KNOWN_VALUES_COUNTER_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
437+ for ( v, i) in KNOWN_VALUES_FEEDBACK_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
438+ let feedback =
439+ Feedback :: < HmacSha256 , HmacSha512 > :: new ( v. iv . map ( GenericArray :: from_slice) ) ;
348440 assert_eq ! (
349- counter. derive(
350- GenericArray :: from_slice( v. key) ,
351- v. use_l,
352- v. use_separator,
353- v. label,
354- v. context,
355- ) ,
356- Ok ( GenericArray :: <_, U128 >:: from_slice( v. expected) . clone( ) ) ,
441+ feedback. derive( v. key, v. use_l, v. use_separator, v. label, v. context, ) ,
442+ Ok ( GenericArray :: <_, _>:: from_slice( v. expected) . clone( ) ) ,
357443 "key derivation failed for (index: {i}):\n {v:x?}"
358444 ) ;
359445 }
360446 }
361447
448+ static KNOWN_VALUES_DOUBLE_PIPELINE_HMAC_SHA256 : & [ KnownValue ] = & [ KnownValue {
449+ iv : None ,
450+ use_l : false , //true,
451+ use_separator : true ,
452+ label : & hex ! ( "921ab061920b191de12f746ac9de08" ) ,
453+ context : & hex ! ( "4f2c20f01775e27bcacdc21ee4a5ff0387758f36d8ec71c7a8c8208284f650b611837e" ) ,
454+ key : & hex ! ( "7d4f86fdfd1c4ba04c674a68d60316d12c99c1b1f44f0a8e02bd2601377ebcd9" ) ,
455+ expected : & hex ! (
456+ "
457+ 506bc2ba51410b2a6e7c05d33891520d dd5f702ad3d6203d76d8dae1216d0783
458+ d8c59fae2e821d8eff2d8ddd93a6741c 8f144fb96e9ca7d7c532468f213f5efe
459+ "
460+ ) ,
461+ } ] ;
462+
362463 #[ test]
363- fn test_static_values_feedback ( ) {
464+ fn test_static_values_double_pipeline ( ) {
364465 type HmacSha256 = hmac:: Hmac < sha2:: Sha256 > ;
365- type HmacSha512 = hmac:: Hmac < sha2:: Sha512 > ;
366466
367- for ( v, i) in KNOWN_VALUES_FEEDBACK_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
368- let feedback =
369- Feedback :: < HmacSha256 , HmacSha512 > :: new ( v. iv . map ( GenericArray :: from_slice) ) ;
467+ struct MockOutput ;
468+
469+ impl KeySizeUser for MockOutput {
470+ type KeySize = U64 ;
471+ }
472+
473+ for ( v, i) in KNOWN_VALUES_DOUBLE_PIPELINE_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
474+ let dbl_pipeline = DoublePipeline :: < HmacSha256 , MockOutput > :: default ( ) ;
370475 assert_eq ! (
371- feedback. derive(
372- GenericArray :: from_slice( v. key) ,
373- v. use_l,
374- v. use_separator,
375- v. label,
376- v. context,
377- ) ,
378- Ok ( GenericArray :: <_, U128 >:: from_slice( v. expected) . clone( ) ) ,
476+ dbl_pipeline. derive( v. key, v. use_l, v. use_separator, v. label, v. context, ) ,
477+ Ok ( GenericArray :: <_, _>:: from_slice( v. expected) . clone( ) ) ,
379478 "key derivation failed for (index: {i}):\n {v:x?}"
380479 ) ;
381480 }
0 commit comments