44use core:: ops:: { Deref , DerefMut } ;
55
66use crate :: low:: ct_equal;
7+ use crate :: mid:: sha1;
78use crate :: mid:: sha2;
89
910/// Output from a hash function.
1011///
1112/// This has one variant per supported hash function.
1213#[ derive( Clone , Debug ) ]
1314pub enum HashOutput {
15+ /// Output from SHA1
16+ Sha1 ( [ u8 ; sha1:: Sha1Context :: OUTPUT_SZ ] ) ,
1417 /// Output from SHA256
1518 Sha256 ( [ u8 ; sha2:: Sha256Context :: OUTPUT_SZ ] ) ,
1619 /// Output from SHA384
@@ -43,6 +46,7 @@ impl HashOutput {
4346impl PartialEq for HashOutput {
4447 fn eq ( & self , other : & Self ) -> bool {
4548 match ( self , other) {
49+ ( Self :: Sha1 ( s) , Self :: Sha1 ( o) ) => ct_equal ( s, o) ,
4650 ( Self :: Sha256 ( s) , Self :: Sha256 ( o) ) => ct_equal ( s, o) ,
4751 ( Self :: Sha384 ( s) , Self :: Sha384 ( o) ) => ct_equal ( s, o) ,
4852 ( Self :: Sha512 ( s) , Self :: Sha512 ( o) ) => ct_equal ( s, o) ,
@@ -54,6 +58,7 @@ impl PartialEq for HashOutput {
5458impl AsRef < [ u8 ] > for HashOutput {
5559 fn as_ref ( & self ) -> & [ u8 ] {
5660 match self {
61+ Self :: Sha1 ( v) => v,
5762 Self :: Sha256 ( v) => v,
5863 Self :: Sha384 ( v) => v,
5964 Self :: Sha512 ( v) => v,
@@ -64,6 +69,7 @@ impl AsRef<[u8]> for HashOutput {
6469impl AsMut < [ u8 ] > for HashOutput {
6570 fn as_mut ( & mut self ) -> & mut [ u8 ] {
6671 match self {
72+ Self :: Sha1 ( v) => v,
6773 Self :: Sha256 ( v) => v,
6874 Self :: Sha384 ( v) => v,
6975 Self :: Sha512 ( v) => v,
@@ -259,12 +265,87 @@ impl HashContext for Sha512Context {
259265 }
260266}
261267
268+ /// This is SHA1.
269+ ///
270+ /// Do not use SHA1 for new applications or for applications involving signatures.
271+ ///
272+ /// This is described in [FIPS180-1](https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub180-1.pdf).
273+ #[ derive( Clone ) ]
274+ pub struct Sha1 ;
275+
276+ impl Hash for Sha1 {
277+ type Context = Sha1Context ;
278+
279+ fn new ( ) -> Self :: Context {
280+ Sha1Context ( sha1:: Sha1Context :: new ( ) )
281+ }
282+
283+ fn hash ( bytes : & [ u8 ] ) -> HashOutput {
284+ let mut ctx = Self :: new ( ) ;
285+ ctx. update ( bytes) ;
286+ ctx. finish ( )
287+ }
288+
289+ fn zeroed_block ( ) -> HashBlock {
290+ HashBlock :: new ( sha1:: Sha1Context :: BLOCK_SZ )
291+ }
292+
293+ fn zeroed_output ( ) -> HashOutput {
294+ HashOutput :: Sha1 ( [ 0u8 ; sha1:: Sha1Context :: OUTPUT_SZ ] )
295+ }
296+ }
297+
298+ #[ derive( Clone ) ]
299+ pub struct Sha1Context ( sha1:: Sha1Context ) ;
300+
301+ impl HashContext for Sha1Context {
302+ fn update ( & mut self , bytes : & [ u8 ] ) {
303+ self . 0 . update ( bytes)
304+ }
305+
306+ fn finish ( self ) -> HashOutput {
307+ HashOutput :: Sha1 ( self . 0 . finish ( ) )
308+ }
309+ }
310+
262311#[ cfg( test) ]
263312#[ cfg_attr( coverage_nightly, coverage( off) ) ]
264313mod tests {
265314 use super :: * ;
266315 use crate :: test:: * ;
267316
317+ #[ test]
318+ fn equality ( ) {
319+ let s1a = Sha1 :: hash ( b"a" ) ;
320+ let s1b = Sha1 :: hash ( b"b" ) ;
321+ let s256a = Sha256 :: hash ( b"a" ) ;
322+ let s256b = Sha256 :: hash ( b"b" ) ;
323+ let s384a = Sha384 :: hash ( b"a" ) ;
324+ let s384b = Sha384 :: hash ( b"b" ) ;
325+ let s512a = Sha512 :: hash ( b"a" ) ;
326+ let s512b = Sha512 :: hash ( b"b" ) ;
327+
328+ assert_eq ! ( s1a, Sha1 :: hash( b"a" ) ) ;
329+ for other in [ & s1b, & s256a, & s384a, & s512a] {
330+ assert_ne ! ( & s1a, other) ;
331+ }
332+
333+ assert_eq ! ( s256a, Sha256 :: hash( b"a" ) ) ;
334+ for other in [ & s1a, & s256b, & s384a, & s512a] {
335+ assert_ne ! ( & s256a, other) ;
336+ }
337+
338+ assert_eq ! ( s384a, Sha384 :: hash( b"a" ) ) ;
339+ for other in [ & s1a, & s256a, & s384b, & s512a] {
340+ assert_ne ! ( & s384a, other) ;
341+ }
342+
343+ assert_eq ! ( s512a, Sha512 :: hash( b"a" ) ) ;
344+ for other in [ & s1a, & s256a, & s384a, & s512b] {
345+ assert_ne ! ( & s512a, other) ;
346+ }
347+ }
348+
268349 #[ test]
269350 fn cavp ( ) {
270351 #[ derive( Debug ) ]
0 commit comments