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,31 +117,61 @@ 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+ }
122136
137+ let mut h = <Prf as Mac >:: new_from_slice ( kin) . unwrap ( ) ;
138+
139+ let mut instring = std:: vec:: Vec :: new ( ) ;
123140 if Self :: FEEDBACK_KI {
124141 if let Some ( ki) = ki {
142+ instring. extend_from_slice ( ki. as_slice ( ) ) ;
125143 h. update ( ki. as_slice ( ) ) ;
126144 }
127145 }
128146
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 ) ..] ) ;
147+ if Self :: DOUBLE_PIPELINE {
148+ instring. extend_from_slice ( a. as_slice ( ) ) ;
149+ h. update ( a. as_slice ( ) ) ;
150+ } else {
151+ // counter encoded as big endian u32
152+ // Type parameter R encodes how large the value is to be (either U8, U16, U24, or U32)
153+ //
154+ // counter = 1u32 ([0, 0, 0, 1])
155+ // \-------/
156+ // R = u24
157+ instring. extend_from_slice ( & counter. to_be_bytes ( ) [ ( 4 - R :: USIZE / 8 ) ..] ) ;
158+ h. update ( & counter. to_be_bytes ( ) [ ( 4 - R :: USIZE / 8 ) ..] ) ;
159+ }
136160
137161 // Fixed input data
162+ instring. extend_from_slice ( label) ;
138163 h. update ( label) ;
139164 if use_separator {
165+ instring. extend_from_slice ( & [ 0 ] ) ;
140166 h. update ( & [ 0 ] ) ;
141167 }
168+ instring. extend_from_slice ( context) ;
142169 h. update ( context) ;
143170 if use_l {
171+ instring. extend_from_slice (
172+ & ( <KbkdfCore < K :: KeySize , Prf :: OutputSize > as KbkdfUser >:: L :: U32 ) . to_be_bytes ( )
173+ [ ..] ,
174+ ) ;
144175 h. update (
145176 & ( <KbkdfCore < K :: KeySize , Prf :: OutputSize > as KbkdfUser >:: L :: U32 ) . to_be_bytes ( )
146177 [ ..] ,
@@ -166,6 +197,8 @@ where
166197
167198 /// Whether the KI should be reinjected every round.
168199 const FEEDBACK_KI : bool = false ;
200+
201+ const DOUBLE_PIPELINE : bool = false ;
169202}
170203
171204pub struct Counter < Prf , K , R = U32 > {
@@ -231,10 +264,41 @@ where
231264 const FEEDBACK_KI : bool = true ;
232265}
233266
267+ pub struct DoublePipeline < Prf , K , R = U32 >
268+ where
269+ Prf : Mac ,
270+ {
271+ _marker : PhantomData < ( Prf , K , R ) > ,
272+ }
273+
274+ impl < Prf , K , R > Default for DoublePipeline < Prf , K , R >
275+ where
276+ Prf : Mac ,
277+ {
278+ fn default ( ) -> Self {
279+ Self {
280+ _marker : PhantomData ,
281+ }
282+ }
283+ }
284+
285+ impl < Prf , K , R > Kbkdf < Prf , K , R > for DoublePipeline < Prf , K , R >
286+ where
287+ Prf : Mac + KeyInit ,
288+ K : KeySizeUser ,
289+ K :: KeySize : ArrayLength < u8 > + Mul < U8 > ,
290+ <K :: KeySize as Mul < U8 > >:: Output : Unsigned ,
291+ Prf :: OutputSize : ArrayLength < u8 > + Mul < U8 > ,
292+ <Prf :: OutputSize as Mul < U8 > >:: Output : Unsigned ,
293+ R : sealed:: R ,
294+ {
295+ const DOUBLE_PIPELINE : bool = true ;
296+ }
297+
234298#[ cfg( test) ]
235299mod tests {
236- use super :: { Counter , Feedback , GenericArray , Kbkdf } ;
237- use digest:: consts:: * ;
300+ use super :: { Counter , DoublePipeline , Feedback , GenericArray , Kbkdf } ;
301+ use digest:: { consts:: * , crypto_common :: KeySizeUser } ;
238302 use hex_literal:: hex;
239303
240304 #[ derive( Debug ) ]
@@ -293,6 +357,44 @@ mod tests {
293357 } ,
294358 ] ;
295359
360+ #[ test]
361+ fn test_static_values_counter ( ) {
362+ type HmacSha256 = hmac:: Hmac < sha2:: Sha256 > ;
363+ type HmacSha512 = hmac:: Hmac < sha2:: Sha512 > ;
364+
365+ let counter = Counter :: < HmacSha256 , HmacSha512 > :: default ( ) ;
366+ for ( v, i) in KNOWN_VALUES_COUNTER_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
367+ assert_eq ! (
368+ counter. derive( v. key, v. use_l, v. use_separator, v. label, v. context, ) ,
369+ Ok ( GenericArray :: <_, _>:: from_slice( v. expected) . clone( ) ) ,
370+ "key derivation failed for (index: {i}):\n {v:x?}"
371+ ) ;
372+ }
373+ }
374+
375+ #[ test]
376+ fn test_counter_kbkdfvs ( ) {
377+ type HmacSha256 = hmac:: Hmac < sha2:: Sha256 > ;
378+ struct MockOutput ;
379+
380+ impl KeySizeUser for MockOutput {
381+ type KeySize = U32 ;
382+ }
383+
384+ let counter = Counter :: < HmacSha256 , MockOutput > :: default ( ) ;
385+ // KDFCTR_gen.txt count 15
386+ assert_eq ! (
387+ counter. derive(
388+ & hex!( "43eef6d824fd820405626ab9b6d79f1fd04e126ab8e17729e3afc7cb5af794f8" ) ,
389+ false ,
390+ false ,
391+ & hex!( "5e269b5a7bdedcc3e875e2725693a257fc60011af7dcd68a3358507fe29b0659ca66951daa05a15032033650bc58a27840f8fbe9f4088b9030738f68" ) ,
392+ & [ ] ,
393+ ) ,
394+ Ok ( GenericArray :: <_, _>:: from_slice( & hex!( "f0a339ecbcae6add1afb27da3ba40a1320c6427a58afb9dc366b219b7eb29ecf" ) ) . clone( ) ) ,
395+ ) ;
396+ }
397+
296398 static KNOWN_VALUES_FEEDBACK_HMAC_SHA256 : & [ KnownValue ] = & [
297399 KnownValue {
298400 iv : Some ( b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ) ,
@@ -339,43 +441,52 @@ mod tests {
339441 ] ;
340442
341443 #[ test]
342- fn test_static_values_counter ( ) {
444+ fn test_static_values_feedback ( ) {
343445 type HmacSha256 = hmac:: Hmac < sha2:: Sha256 > ;
344446 type HmacSha512 = hmac:: Hmac < sha2:: Sha512 > ;
345447
346- let counter = Counter :: < HmacSha256 , HmacSha512 > :: default ( ) ;
347- for ( v, i) in KNOWN_VALUES_COUNTER_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
448+ for ( v, i) in KNOWN_VALUES_FEEDBACK_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
449+ let feedback =
450+ Feedback :: < HmacSha256 , HmacSha512 > :: new ( v. iv . map ( GenericArray :: from_slice) ) ;
348451 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( ) ) ,
452+ feedback. derive( v. key, v. use_l, v. use_separator, v. label, v. context, ) ,
453+ Ok ( GenericArray :: <_, _>:: from_slice( v. expected) . clone( ) ) ,
357454 "key derivation failed for (index: {i}):\n {v:x?}"
358455 ) ;
359456 }
360457 }
361458
459+ static KNOWN_VALUES_DOUBLE_PIPELINE_HMAC_SHA256 : & [ KnownValue ] = & [ KnownValue {
460+ iv : None ,
461+ use_l : false , //true,
462+ use_separator : true ,
463+ label : & hex ! ( "921ab061920b191de12f746ac9de08" ) ,
464+ context : & hex ! ( "4f2c20f01775e27bcacdc21ee4a5ff0387758f36d8ec71c7a8c8208284f650b611837e" ) ,
465+ key : & hex ! ( "7d4f86fdfd1c4ba04c674a68d60316d12c99c1b1f44f0a8e02bd2601377ebcd9" ) ,
466+ expected : & hex ! (
467+ "
468+ 506bc2ba51410b2a6e7c05d33891520d dd5f702ad3d6203d76d8dae1216d0783
469+ d8c59fae2e821d8eff2d8ddd93a6741c 8f144fb96e9ca7d7c532468f213f5efe
470+ "
471+ ) ,
472+ } ] ;
473+
362474 #[ test]
363- fn test_static_values_feedback ( ) {
475+ fn test_static_values_double_pipeline ( ) {
364476 type HmacSha256 = hmac:: Hmac < sha2:: Sha256 > ;
365477 type HmacSha512 = hmac:: Hmac < sha2:: Sha512 > ;
366478
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) ) ;
479+ struct MockOutput ;
480+
481+ impl KeySizeUser for MockOutput {
482+ type KeySize = U64 ;
483+ }
484+
485+ for ( v, i) in KNOWN_VALUES_DOUBLE_PIPELINE_HMAC_SHA256 . iter ( ) . zip ( 0 ..) {
486+ let dbl_pipeline = DoublePipeline :: < HmacSha256 , MockOutput > :: default ( ) ;
370487 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( ) ) ,
488+ dbl_pipeline. derive( v. key, v. use_l, v. use_separator, v. label, v. context, ) ,
489+ Ok ( GenericArray :: <_, _>:: from_slice( v. expected) . clone( ) ) ,
379490 "key derivation failed for (index: {i}):\n {v:x?}"
380491 ) ;
381492 }
0 commit comments