@@ -199,6 +199,7 @@ unsafe impl Send for MessageDigest {}
199
199
enum State {
200
200
Reset ,
201
201
Updated ,
202
+ Squeeze ,
202
203
Finalized ,
203
204
}
204
205
@@ -265,6 +266,7 @@ impl Hasher {
265
266
Updated => {
266
267
self . finish ( ) ?;
267
268
}
269
+ Squeeze => ( ) ,
268
270
Finalized => ( ) ,
269
271
}
270
272
unsafe {
@@ -290,6 +292,21 @@ impl Hasher {
290
292
Ok ( ( ) )
291
293
}
292
294
295
+ /// Squeezes buf out of the hasher.
296
+ /// The output will be as long as the buf.
297
+ #[ cfg( ossl330) ]
298
+ pub fn squeeze_xof ( & mut self , buf : & mut [ u8 ] ) -> Result < ( ) , ErrorStack > {
299
+ unsafe {
300
+ cvt ( ffi:: EVP_DigestSqueeze (
301
+ self . ctx ,
302
+ buf. as_mut_ptr ( ) ,
303
+ buf. len ( ) ,
304
+ ) ) ?;
305
+ self . state = Squeeze ;
306
+ Ok ( ( ) )
307
+ }
308
+ }
309
+
293
310
/// Returns the hash of the data written and resets the non-XOF hasher.
294
311
pub fn finish ( & mut self ) -> Result < DigestBytes , ErrorStack > {
295
312
if self . state == Finalized {
@@ -486,6 +503,21 @@ mod tests {
486
503
assert_eq ! ( buf, expected) ;
487
504
}
488
505
506
+ /// Squeezes the expected length by doing two squeezes.
507
+ #[ cfg( ossl330) ]
508
+ fn hash_xof_squeeze_test ( hashtype : MessageDigest , hashtest : & ( & str , & str ) ) {
509
+ let data = Vec :: from_hex ( hashtest. 0 ) . unwrap ( ) ;
510
+ let mut h = Hasher :: new ( hashtype) . unwrap ( ) ;
511
+ h. update ( & data) . unwrap ( ) ;
512
+
513
+ let expected = Vec :: from_hex ( hashtest. 1 ) . unwrap ( ) ;
514
+ let mut buf = vec ! [ 0 ; expected. len( ) ] ;
515
+ assert ! ( expected. len( ) > 10 ) ;
516
+ h. squeeze_xof ( & mut buf[ ..10 ] ) . unwrap ( ) ;
517
+ h. squeeze_xof ( & mut buf[ 10 ..] ) . unwrap ( ) ;
518
+ assert_eq ! ( buf, expected) ;
519
+ }
520
+
489
521
fn hash_recycle_test ( h : & mut Hasher , hashtest : & ( & str , & str ) ) {
490
522
h. write_all ( & Vec :: from_hex ( hashtest. 0 ) . unwrap ( ) ) . unwrap ( ) ;
491
523
let res = h. finish ( ) . unwrap ( ) ;
@@ -715,6 +747,8 @@ mod tests {
715
747
716
748
for test in tests. iter ( ) {
717
749
hash_xof_test ( MessageDigest :: shake_128 ( ) , test) ;
750
+ #[ cfg( ossl330) ]
751
+ hash_xof_squeeze_test ( MessageDigest :: shake_128 ( ) , test) ;
718
752
}
719
753
720
754
assert_eq ! ( MessageDigest :: shake_128( ) . block_size( ) , 168 ) ;
@@ -735,6 +769,8 @@ mod tests {
735
769
736
770
for test in tests. iter ( ) {
737
771
hash_xof_test ( MessageDigest :: shake_256 ( ) , test) ;
772
+ #[ cfg( ossl330) ]
773
+ hash_xof_squeeze_test ( MessageDigest :: shake_256 ( ) , test) ;
738
774
}
739
775
740
776
assert_eq ! ( MessageDigest :: shake_256( ) . block_size( ) , 136 ) ;
0 commit comments