10
10
11
11
use std:: uint;
12
12
13
- use cryptoutil:: { write_u64_be, write_u32_be, read_u64v_be, read_u32v_be, FixedBuffer ,
14
- FixedBuffer128 , FixedBuffer64 , StandardPadding } ;
13
+ use cryptoutil:: { write_u64_be, write_u32_be, read_u64v_be, read_u32v_be, shift_add_check_overflow ,
14
+ shift_add_check_overflow_tuple , FixedBuffer , FixedBuffer128 , FixedBuffer64 , StandardPadding } ;
15
15
use digest:: Digest ;
16
16
17
17
@@ -34,47 +34,6 @@ macro_rules! sha2_round(
34
34
)
35
35
36
36
37
- // BitCounter is a specialized structure intended simply for counting the
38
- // number of bits that have been processed by the SHA-2 512 family of functions.
39
- // It does very little overflow checking since such checking is not necessary
40
- // for how it is used. A more generic structure would have to do this checking.
41
- // So, don't copy this structure and use it elsewhere!
42
- struct BitCounter {
43
- high_bit_count : u64 ,
44
- low_byte_count : u64
45
- }
46
-
47
- impl BitCounter {
48
- fn new ( ) -> BitCounter {
49
- return BitCounter {
50
- high_bit_count : 0 ,
51
- low_byte_count : 0
52
- } ;
53
- }
54
-
55
- fn add_bytes ( & mut self , bytes : uint ) {
56
- self . low_byte_count += bytes as u64 ;
57
- if ( self . low_byte_count > 0x1fffffffffffffffu64 ) {
58
- self . high_bit_count += ( self . low_byte_count >> 61 ) ;
59
- self . low_byte_count &= 0x1fffffffffffffffu64 ;
60
- }
61
- }
62
-
63
- fn reset ( & mut self ) {
64
- self . low_byte_count = 0 ;
65
- self . high_bit_count = 0 ;
66
- }
67
-
68
- fn get_low_bit_count ( & self ) -> u64 {
69
- self . low_byte_count << 3
70
- }
71
-
72
- fn get_high_bit_count ( & self ) -> u64 {
73
- self . high_bit_count
74
- }
75
- }
76
-
77
-
78
37
// A structure that represents that state of a digest computation for the SHA-2 512 family of digest
79
38
// functions
80
39
struct Engine512State {
@@ -223,7 +182,7 @@ static K64: [u64, ..80] = [
223
182
// A structure that keeps track of the state of the Sha-512 operation and contains the logic
224
183
// necessary to perform the final calculations.
225
184
struct Engine512 {
226
- bit_counter : BitCounter ,
185
+ length_bits : ( u64 , u64 ) ,
227
186
buffer : FixedBuffer128 ,
228
187
state : Engine512State ,
229
188
finished : bool ,
@@ -232,23 +191,24 @@ struct Engine512 {
232
191
impl Engine512 {
233
192
fn new( h : & [ u64 , ..8 ] ) -> Engine512 {
234
193
return Engine512 {
235
- bit_counter : BitCounter :: new ( ) ,
194
+ length_bits : ( 0 , 0 ) ,
236
195
buffer : FixedBuffer128 :: new( ) ,
237
196
state : Engine512State :: new( h) ,
238
197
finished : false
239
198
}
240
199
}
241
200
242
201
fn reset( & mut self , h : & [ u64 , ..8 ] ) {
243
- self . bit_counter . reset ( ) ;
202
+ self . length_bits = ( 0 , 0 ) ;
244
203
self . buffer. reset( ) ;
245
204
self . state. reset( h) ;
246
205
self . finished = false ;
247
206
}
248
207
249
208
fn input ( & mut self , in : & [ u8 ] ) {
250
209
assert!( !self . finished)
251
- self . bit_counter. add_bytes( in. len( ) ) ;
210
+ // Assumes that in.len() can be converted to u64 without overflow
211
+ self . length_bits = shift_add_check_overflow_tuple( self . length_bits, in. len( ) as u64 , 3 ) ;
252
212
self . buffer. input( in, |in: & [ u8 ] | { self . state. process_block( in) } ) ;
253
213
}
254
214
@@ -258,8 +218,12 @@ impl Engine512 {
258
218
}
259
219
260
220
self . buffer. standard_padding( 16 , |in: & [ u8 ] | { self . state. process_block( in) } ) ;
261
- write_u64_be( self . buffer. next( 8 ) , self . bit_counter. get_high_bit_count( ) ) ;
262
- write_u64_be( self . buffer. next( 8 ) , self . bit_counter. get_low_bit_count( ) ) ;
221
+ match self . length_bits {
222
+ ( hi, low) => {
223
+ write_u64_be( self . buffer. next( 8 ) , hi) ;
224
+ write_u64_be( self . buffer. next( 8 ) , low) ;
225
+ }
226
+ }
263
227
self . state. process_block( self . buffer. full_buffer( ) ) ;
264
228
265
229
self . finished = true ;
@@ -608,7 +572,7 @@ static K32: [u32, ..64] = [
608
572
// A structure that keeps track of the state of the Sha-256 operation and contains the logic
609
573
// necessary to perform the final calculations.
610
574
struct Engine256 {
611
- length : u64 ,
575
+ length_bits : u64 ,
612
576
buffer: FixedBuffer64 ,
613
577
state: Engine256State ,
614
578
finished: bool ,
@@ -617,23 +581,24 @@ struct Engine256 {
617
581
impl Engine256 {
618
582
fn new( h: & [ u32 , ..8 ] ) -> Engine256 {
619
583
return Engine256 {
620
- length : 0 ,
584
+ length_bits : 0 ,
621
585
buffer: FixedBuffer64 :: new( ) ,
622
586
state: Engine256State :: new( h) ,
623
587
finished: false
624
588
}
625
589
}
626
590
627
591
fn reset( & mut self , h: & [ u32 , ..8 ] ) {
628
- self . length = 0 ;
592
+ self . length_bits = 0 ;
629
593
self . buffer. reset( ) ;
630
594
self . state. reset( h) ;
631
595
self . finished = false ;
632
596
}
633
597
634
598
fn input( & mut self , in: & [ u8 ] ) {
635
599
assert!( !self . finished)
636
- self . length += in. len( ) as u64 ;
600
+ // Assumes that in.len() can be converted to u64 without overflow
601
+ self . length_bits = shift_add_check_overflow( self . length_bits, in. len( ) as u64 , 3 ) ;
637
602
self . buffer. input( in, |in: & [ u8 ] | { self . state. process_block( in) } ) ;
638
603
}
639
604
@@ -643,8 +608,8 @@ impl Engine256 {
643
608
}
644
609
645
610
self . buffer. standard_padding( 8 , |in: & [ u8 ] | { self . state. process_block( in) } ) ;
646
- write_u32_be( self . buffer. next( 4 ) , ( self . length >> 29 ) as u32 ) ;
647
- write_u32_be( self . buffer. next( 4 ) , ( self . length << 3 ) as u32 ) ;
611
+ write_u32_be( self . buffer. next( 4 ) , ( self . length_bits >> 32 ) as u32 ) ;
612
+ write_u32_be( self . buffer. next( 4 ) , self . length_bits as u32 ) ;
648
613
self . state. process_block( self . buffer. full_buffer( ) ) ;
649
614
650
615
self . finished = true ;
0 commit comments