File Coverage

blib/lib/Digest/SHA/PurePerl.pm
Criterion Covered Total %
statement 982 1145 85.7
branch 143 262 54.5
condition 9 18 50.0
subroutine 127 158 80.3
pod 56 56 100.0
total 1317 1639 80.3


line stmt bran cond sub pod time code
1             package Digest::SHA::PurePerl;
2              
3             require 5.003000;
4              
5 24     24   25900 use strict;
  24         187  
  24         661  
6 24     24   128 use warnings;
  24         54  
  24         943  
7 24     24   156 use vars qw($VERSION @ISA @EXPORT_OK $errmsg);
  24         66  
  24         2427  
8 24     24   154 use Fcntl qw(O_RDONLY O_RDWR);
  24         74  
  24         1529  
9 24     24   169 use Cwd qw(getcwd);
  24         61  
  24         1345  
10 24     24   12633 use integer;
  24         385  
  24         133  
11 24     24   814 use Carp qw(croak);
  24         55  
  24         114898  
12              
13             $VERSION = '6.04';
14              
15             require Exporter;
16             @ISA = qw(Exporter);
17             @EXPORT_OK = ('$errmsg'); # see "SHA and HMAC-SHA functions" below
18              
19             # Inherit from Digest::base if possible
20              
21             eval {
22             require Digest::base;
23             push(@ISA, 'Digest::base');
24             };
25              
26             # ref. src/sha.c and sha/sha64bit.c from Digest::SHA
27              
28             my $MAX32 = 0xffffffff;
29              
30             my $uses64bit = (((1 << 16) << 16) << 16) << 15;
31              
32             my @H01 = ( # SHA-1 initial hash value
33             0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
34             0xc3d2e1f0
35             );
36              
37             my @H0224 = ( # SHA-224 initial hash value
38             0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
39             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
40             );
41              
42             my @H0256 = ( # SHA-256 initial hash value
43             0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
44             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
45             );
46              
47             my(@H0384, @H0512, @H0512224, @H0512256); # filled in later if $uses64bit
48              
49             # Routines with a "_c_" prefix return Perl code-fragments which are
50             # eval'ed at initialization. This technique emulates the behavior
51             # of the C preprocessor, allowing the optimized transform code from
52             # Digest::SHA to be more easily translated into Perl.
53              
54             sub _c_SL32 { # code to shift $x left by $n bits
55 19200     19200   29097 my($x, $n) = @_;
56 19200         52469 "($x << $n)"; # even works for 64-bit integers
57             # since the upper 32 bits are
58             # eventually discarded in _digcpy
59             }
60              
61             sub _c_SR32 { # code to shift $x right by $n bits
62 21504     21504   31851 my($x, $n) = @_;
63 21504         30035 my $mask = (1 << (32 - $n)) - 1;
64 21504         108055 "(($x >> $n) & $mask)"; # "use integer" does arithmetic
65             # shift, so clear upper bits
66             }
67              
68 2016     2016   3474 sub _c_Ch { my($x, $y, $z) = @_; "($z ^ ($x & ($y ^ $z)))" }
  2016         6234  
69 960     960   1664 sub _c_Pa { my($x, $y, $z) = @_; "($x ^ $y ^ $z)" }
  960         2991  
70 2016     2016   3532 sub _c_Ma { my($x, $y, $z) = @_; "(($x & $y) | ($z & ($x | $y)))" }
  2016         12055  
71              
72             sub _c_ROTR { # code to rotate $x right by $n bits
73 13824     13824   21023 my($x, $n) = @_;
74 13824         20441 "(" . _c_SR32($x, $n) . " | " . _c_SL32($x, 32 - $n) . ")";
75             }
76              
77             sub _c_ROTL { # code to rotate $x left by $n bits
78 5376     5376   8410 my($x, $n) = @_;
79 5376         8280 "(" . _c_SL32($x, $n) . " | " . _c_SR32($x, 32 - $n) . ")";
80             }
81              
82             sub _c_SIGMA0 { # ref. NIST SHA standard
83 1536     1536   2374 my($x) = @_;
84 1536         2361 "(" . _c_ROTR($x, 2) . " ^ " . _c_ROTR($x, 13) . " ^ " .
85             _c_ROTR($x, 22) . ")";
86             }
87              
88             sub _c_SIGMA1 {
89 1536     1536   2219 my($x) = @_;
90 1536         2357 "(" . _c_ROTR($x, 6) . " ^ " . _c_ROTR($x, 11) . " ^ " .
91             _c_ROTR($x, 25) . ")";
92             }
93              
94             sub _c_sigma0 {
95 1152     1152   1794 my($x) = @_;
96 1152         1748 "(" . _c_ROTR($x, 7) . " ^ " . _c_ROTR($x, 18) . " ^ " .
97             _c_SR32($x, 3) . ")";
98             }
99              
100             sub _c_sigma1 {
101 1152     1152   1821 my($x) = @_;
102 1152         1782 "(" . _c_ROTR($x, 17) . " ^ " . _c_ROTR($x, 19) . " ^ " .
103             _c_SR32($x, 10) . ")";
104             }
105              
106             sub _c_M1Ch { # ref. Digest::SHA sha.c (sha1 routine)
107 480     480   912 my($a, $b, $c, $d, $e, $k, $w) = @_;
108 480         843 "$e += " . _c_ROTL($a, 5) . " + " . _c_Ch($b, $c, $d) .
109             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
110             }
111              
112             sub _c_M1Pa {
113 960     960   1711 my($a, $b, $c, $d, $e, $k, $w) = @_;
114 960         1632 "$e += " . _c_ROTL($a, 5) . " + " . _c_Pa($b, $c, $d) .
115             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
116             }
117              
118             sub _c_M1Ma {
119 480     480   898 my($a, $b, $c, $d, $e, $k, $w) = @_;
120 480         903 "$e += " . _c_ROTL($a, 5) . " + " . _c_Ma($b, $c, $d) .
121             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
122             }
123              
124 96     96   198 sub _c_M11Ch { my($k, $w) = @_; _c_M1Ch('$a', '$b', '$c', '$d', '$e', $k, $w) }
  96         187  
125 192     192   378 sub _c_M11Pa { my($k, $w) = @_; _c_M1Pa('$a', '$b', '$c', '$d', '$e', $k, $w) }
  192         360  
126 96     96   216 sub _c_M11Ma { my($k, $w) = @_; _c_M1Ma('$a', '$b', '$c', '$d', '$e', $k, $w) }
  96         229  
127 96     96   219 sub _c_M12Ch { my($k, $w) = @_; _c_M1Ch('$e', '$a', '$b', '$c', '$d', $k, $w) }
  96         237  
128 192     192   380 sub _c_M12Pa { my($k, $w) = @_; _c_M1Pa('$e', '$a', '$b', '$c', '$d', $k, $w) }
  192         413  
129 96     96   193 sub _c_M12Ma { my($k, $w) = @_; _c_M1Ma('$e', '$a', '$b', '$c', '$d', $k, $w) }
  96         217  
130 96     96   192 sub _c_M13Ch { my($k, $w) = @_; _c_M1Ch('$d', '$e', '$a', '$b', '$c', $k, $w) }
  96         583  
131 192     192   386 sub _c_M13Pa { my($k, $w) = @_; _c_M1Pa('$d', '$e', '$a', '$b', '$c', $k, $w) }
  192         373  
132 96     96   189 sub _c_M13Ma { my($k, $w) = @_; _c_M1Ma('$d', '$e', '$a', '$b', '$c', $k, $w) }
  96         427  
133 96     96   193 sub _c_M14Ch { my($k, $w) = @_; _c_M1Ch('$c', '$d', '$e', '$a', '$b', $k, $w) }
  96         187  
134 192     192   396 sub _c_M14Pa { my($k, $w) = @_; _c_M1Pa('$c', '$d', '$e', '$a', '$b', $k, $w) }
  192         353  
135 96     96   185 sub _c_M14Ma { my($k, $w) = @_; _c_M1Ma('$c', '$d', '$e', '$a', '$b', $k, $w) }
  96         214  
136 96     96   210 sub _c_M15Ch { my($k, $w) = @_; _c_M1Ch('$b', '$c', '$d', '$e', '$a', $k, $w) }
  96         184  
137 192     192   356 sub _c_M15Pa { my($k, $w) = @_; _c_M1Pa('$b', '$c', '$d', '$e', '$a', $k, $w) }
  192         375  
138 96     96   3791 sub _c_M15Ma { my($k, $w) = @_; _c_M1Ma('$b', '$c', '$d', '$e', '$a', $k, $w) }
  96         1788  
139              
140 3072     3072   4479 sub _c_W11 { my($s) = @_; '$W[' . (($s + 0) & 0xf) . ']' }
  3072         7484  
141 1536     1536   2649 sub _c_W12 { my($s) = @_; '$W[' . (($s + 13) & 0xf) . ']' }
  1536         3276  
142 1536     1536   2317 sub _c_W13 { my($s) = @_; '$W[' . (($s + 8) & 0xf) . ']' }
  1536         3324  
143 1536     1536   2329 sub _c_W14 { my($s) = @_; '$W[' . (($s + 2) & 0xf) . ']' }
  1536         2956  
144              
145             sub _c_A1 {
146 1536     1536   2713 my($s) = @_;
147 1536         2468 my $tmp = _c_W11($s) . " ^ " . _c_W12($s) . " ^ " .
148             _c_W13($s) . " ^ " . _c_W14($s);
149 1536         3198 "((\$tmp = $tmp), (" . _c_W11($s) . " = " . _c_ROTL('$tmp', 1) . "))";
150             }
151              
152             # The following code emulates the "sha1" routine from Digest::SHA sha.c
153              
154             my $sha1_code = '
155              
156             my($K1, $K2, $K3, $K4) = ( # SHA-1 constants
157             0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
158             );
159              
160             sub _sha1 {
161             my($self, $block) = @_;
162             my(@W, $a, $b, $c, $d, $e, $tmp);
163              
164             @W = unpack("N16", $block);
165             ($a, $b, $c, $d, $e) = @{$self->{H}};
166             ' .
167             _c_M11Ch('$K1', '$W[ 0]' ) . _c_M12Ch('$K1', '$W[ 1]' ) .
168             _c_M13Ch('$K1', '$W[ 2]' ) . _c_M14Ch('$K1', '$W[ 3]' ) .
169             _c_M15Ch('$K1', '$W[ 4]' ) . _c_M11Ch('$K1', '$W[ 5]' ) .
170             _c_M12Ch('$K1', '$W[ 6]' ) . _c_M13Ch('$K1', '$W[ 7]' ) .
171             _c_M14Ch('$K1', '$W[ 8]' ) . _c_M15Ch('$K1', '$W[ 9]' ) .
172             _c_M11Ch('$K1', '$W[10]' ) . _c_M12Ch('$K1', '$W[11]' ) .
173             _c_M13Ch('$K1', '$W[12]' ) . _c_M14Ch('$K1', '$W[13]' ) .
174             _c_M15Ch('$K1', '$W[14]' ) . _c_M11Ch('$K1', '$W[15]' ) .
175             _c_M12Ch('$K1', _c_A1( 0) ) . _c_M13Ch('$K1', _c_A1( 1) ) .
176             _c_M14Ch('$K1', _c_A1( 2) ) . _c_M15Ch('$K1', _c_A1( 3) ) .
177             _c_M11Pa('$K2', _c_A1( 4) ) . _c_M12Pa('$K2', _c_A1( 5) ) .
178             _c_M13Pa('$K2', _c_A1( 6) ) . _c_M14Pa('$K2', _c_A1( 7) ) .
179             _c_M15Pa('$K2', _c_A1( 8) ) . _c_M11Pa('$K2', _c_A1( 9) ) .
180             _c_M12Pa('$K2', _c_A1(10) ) . _c_M13Pa('$K2', _c_A1(11) ) .
181             _c_M14Pa('$K2', _c_A1(12) ) . _c_M15Pa('$K2', _c_A1(13) ) .
182             _c_M11Pa('$K2', _c_A1(14) ) . _c_M12Pa('$K2', _c_A1(15) ) .
183             _c_M13Pa('$K2', _c_A1( 0) ) . _c_M14Pa('$K2', _c_A1( 1) ) .
184             _c_M15Pa('$K2', _c_A1( 2) ) . _c_M11Pa('$K2', _c_A1( 3) ) .
185             _c_M12Pa('$K2', _c_A1( 4) ) . _c_M13Pa('$K2', _c_A1( 5) ) .
186             _c_M14Pa('$K2', _c_A1( 6) ) . _c_M15Pa('$K2', _c_A1( 7) ) .
187             _c_M11Ma('$K3', _c_A1( 8) ) . _c_M12Ma('$K3', _c_A1( 9) ) .
188             _c_M13Ma('$K3', _c_A1(10) ) . _c_M14Ma('$K3', _c_A1(11) ) .
189             _c_M15Ma('$K3', _c_A1(12) ) . _c_M11Ma('$K3', _c_A1(13) ) .
190             _c_M12Ma('$K3', _c_A1(14) ) . _c_M13Ma('$K3', _c_A1(15) ) .
191             _c_M14Ma('$K3', _c_A1( 0) ) . _c_M15Ma('$K3', _c_A1( 1) ) .
192             _c_M11Ma('$K3', _c_A1( 2) ) . _c_M12Ma('$K3', _c_A1( 3) ) .
193             _c_M13Ma('$K3', _c_A1( 4) ) . _c_M14Ma('$K3', _c_A1( 5) ) .
194             _c_M15Ma('$K3', _c_A1( 6) ) . _c_M11Ma('$K3', _c_A1( 7) ) .
195             _c_M12Ma('$K3', _c_A1( 8) ) . _c_M13Ma('$K3', _c_A1( 9) ) .
196             _c_M14Ma('$K3', _c_A1(10) ) . _c_M15Ma('$K3', _c_A1(11) ) .
197             _c_M11Pa('$K4', _c_A1(12) ) . _c_M12Pa('$K4', _c_A1(13) ) .
198             _c_M13Pa('$K4', _c_A1(14) ) . _c_M14Pa('$K4', _c_A1(15) ) .
199             _c_M15Pa('$K4', _c_A1( 0) ) . _c_M11Pa('$K4', _c_A1( 1) ) .
200             _c_M12Pa('$K4', _c_A1( 2) ) . _c_M13Pa('$K4', _c_A1( 3) ) .
201             _c_M14Pa('$K4', _c_A1( 4) ) . _c_M15Pa('$K4', _c_A1( 5) ) .
202             _c_M11Pa('$K4', _c_A1( 6) ) . _c_M12Pa('$K4', _c_A1( 7) ) .
203             _c_M13Pa('$K4', _c_A1( 8) ) . _c_M14Pa('$K4', _c_A1( 9) ) .
204             _c_M15Pa('$K4', _c_A1(10) ) . _c_M11Pa('$K4', _c_A1(11) ) .
205             _c_M12Pa('$K4', _c_A1(12) ) . _c_M13Pa('$K4', _c_A1(13) ) .
206             _c_M14Pa('$K4', _c_A1(14) ) . _c_M15Pa('$K4', _c_A1(15) ) .
207              
208             ' $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
209             $self->{H}->[3] += $d; $self->{H}->[4] += $e;
210             }
211             ';
212              
213 921     921   3167 eval($sha1_code);
  921         1636  
  921         2740  
  921         1488  
  921         2094  
  921         2392  
  921         1660  
  921         1741  
  921         1881  
  921         1742  
  921         1562  
  921         2087  
  921         1477  
  921         1739  
  921         1479  
  921         1801  
  921         1525  
  921         1694  
  921         1439  
  921         1686  
  921         1459  
  921         1705  
  921         1480  
  921         1746  
  921         1570  
  921         1636  
  921         1457  
  921         1725  
  921         1439  
  921         2103  
  921         1468  
  921         1613  
  921         1404  
  921         1758  
  921         1402  
  921         1636  
  921         1434  
  921         2290  
  921         1506  
  921         2216  
  921         1513  
  921         2243  
  921         1513  
  921         2222  
  921         1561  
  921         2154  
  921         1499  
  921         2032  
  921         1488  
  921         1990  
  921         1506  
  921         2026  
  921         1496  
  921         2155  
  921         1580  
  921         2172  
  921         1463  
  921         2142  
  921         1469  
  921         2238  
  921         1459  
  921         2088  
  921         1478  
  921         2075  
  921         1436  
  921         2081  
  921         1463  
  921         2191  
  921         1475  
  921         2256  
  921         1476  
  921         2055  
  921         1487  
  921         2061  
  921         1462  
  921         2039  
  921         1478  
  921         2071  
  921         1441  
  921         2136  
  921         1455  
  921         2119  
  921         1522  
  921         2161  
  921         1517  
  921         2249  
  921         1457  
  921         2151  
  921         1414  
  921         2242  
  921         1599  
  921         2274  
  921         1451  
  921         2347  
  921         1560  
  921         2230  
  921         1484  
  921         2258  
  921         1551  
  921         2222  
  921         1435  
  921         2076  
  921         1487  
  921         2172  
  921         1436  
  921         2334  
  921         1428  
  921         2246  
  921         1457  
  921         2241  
  921         1480  
  921         2198  
  921         1444  
  921         2238  
  921         1572  
  921         2192  
  921         1548  
  921         2114  
  921         1572  
  921         2164  
  921         1464  
  921         2264  
  921         1475  
  921         2223  
  921         1543  
  921         2041  
  921         1487  
  921         2141  
  921         1471  
  921         2264  
  921         1485  
  921         2215  
  921         1531  
  921         2191  
  921         1542  
  921         2121  
  921         1479  
  921         2183  
  921         1953  
  921         2128  
  921         1484  
  921         2132  
  921         1511  
  921         2329  
  921         1491  
  921         2130  
  921         1430  
  921         2083  
  921         1559  
  921         2253  
  921         1554  
  921         2193  
  921         1497  
  921         2103  
  921         1463  
  921         2058  
  921         1483  
  921         2309  
  921         1513  
  921         1994  
  921         1532  
  921         2015  
  921         1449  
  921         2151  
  921         1514  
  921         1749  
  921         1302  
  921         1420  
  921         1370  
  921         3410  
214              
215             sub _c_M2 { # ref. Digest::SHA sha.c (sha256 routine)
216 1536     1536   3097 my($a, $b, $c, $d, $e, $f, $g, $h, $w) = @_;
217 1536         2817 "\$T1 = $h + " . _c_SIGMA1($e) . " + " . _c_Ch($e, $f, $g) .
218             " + \$K256[\$i++] + $w; $h = \$T1 + " . _c_SIGMA0($a) .
219             " + " . _c_Ma($a, $b, $c) . "; $d += \$T1;\n";
220             }
221              
222 192     192   433 sub _c_M21 { _c_M2('$a', '$b', '$c', '$d', '$e', '$f', '$g', '$h', $_[0]) }
223 192     192   422 sub _c_M22 { _c_M2('$h', '$a', '$b', '$c', '$d', '$e', '$f', '$g', $_[0]) }
224 192     192   469 sub _c_M23 { _c_M2('$g', '$h', '$a', '$b', '$c', '$d', '$e', '$f', $_[0]) }
225 192     192   429 sub _c_M24 { _c_M2('$f', '$g', '$h', '$a', '$b', '$c', '$d', '$e', $_[0]) }
226 192     192   406 sub _c_M25 { _c_M2('$e', '$f', '$g', '$h', '$a', '$b', '$c', '$d', $_[0]) }
227 192     192   424 sub _c_M26 { _c_M2('$d', '$e', '$f', '$g', '$h', '$a', '$b', '$c', $_[0]) }
228 192     192   405 sub _c_M27 { _c_M2('$c', '$d', '$e', '$f', '$g', '$h', '$a', '$b', $_[0]) }
229 192     192   405 sub _c_M28 { _c_M2('$b', '$c', '$d', '$e', '$f', '$g', '$h', '$a', $_[0]) }
230              
231 1152     1152   2074 sub _c_W21 { my($s) = @_; '$W[' . (($s + 0) & 0xf) . ']' }
  1152         3049  
232 1152     1152   1775 sub _c_W22 { my($s) = @_; '$W[' . (($s + 14) & 0xf) . ']' }
  1152         2507  
233 1152     1152   1928 sub _c_W23 { my($s) = @_; '$W[' . (($s + 9) & 0xf) . ']' }
  1152         2704  
234 1152     1152   1783 sub _c_W24 { my($s) = @_; '$W[' . (($s + 1) & 0xf) . ']' }
  1152         2516  
235              
236             sub _c_A2 {
237 1152     1152   1975 my($s) = @_;
238 1152         1853 "(" . _c_W21($s) . " += " . _c_sigma1(_c_W22($s)) . " + " .
239             _c_W23($s) . " + " . _c_sigma0(_c_W24($s)) . ")";
240             }
241              
242             # The following code emulates the "sha256" routine from Digest::SHA sha.c
243              
244             my $sha256_code = '
245              
246             my @K256 = ( # SHA-224/256 constants
247             0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
248             0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
249             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
250             0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
251             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
252             0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
253             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
254             0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
255             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
256             0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
257             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
258             0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
259             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
260             0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
261             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
262             0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
263             );
264              
265             sub _sha256 {
266             my($self, $block) = @_;
267             my(@W, $a, $b, $c, $d, $e, $f, $g, $h, $i, $T1);
268              
269             @W = unpack("N16", $block);
270             ($a, $b, $c, $d, $e, $f, $g, $h) = @{$self->{H}};
271             ' .
272             _c_M21('$W[ 0]' ) . _c_M22('$W[ 1]' ) . _c_M23('$W[ 2]' ) .
273             _c_M24('$W[ 3]' ) . _c_M25('$W[ 4]' ) . _c_M26('$W[ 5]' ) .
274             _c_M27('$W[ 6]' ) . _c_M28('$W[ 7]' ) . _c_M21('$W[ 8]' ) .
275             _c_M22('$W[ 9]' ) . _c_M23('$W[10]' ) . _c_M24('$W[11]' ) .
276             _c_M25('$W[12]' ) . _c_M26('$W[13]' ) . _c_M27('$W[14]' ) .
277             _c_M28('$W[15]' ) .
278             _c_M21(_c_A2( 0)) . _c_M22(_c_A2( 1)) . _c_M23(_c_A2( 2)) .
279             _c_M24(_c_A2( 3)) . _c_M25(_c_A2( 4)) . _c_M26(_c_A2( 5)) .
280             _c_M27(_c_A2( 6)) . _c_M28(_c_A2( 7)) . _c_M21(_c_A2( 8)) .
281             _c_M22(_c_A2( 9)) . _c_M23(_c_A2(10)) . _c_M24(_c_A2(11)) .
282             _c_M25(_c_A2(12)) . _c_M26(_c_A2(13)) . _c_M27(_c_A2(14)) .
283             _c_M28(_c_A2(15)) . _c_M21(_c_A2( 0)) . _c_M22(_c_A2( 1)) .
284             _c_M23(_c_A2( 2)) . _c_M24(_c_A2( 3)) . _c_M25(_c_A2( 4)) .
285             _c_M26(_c_A2( 5)) . _c_M27(_c_A2( 6)) . _c_M28(_c_A2( 7)) .
286             _c_M21(_c_A2( 8)) . _c_M22(_c_A2( 9)) . _c_M23(_c_A2(10)) .
287             _c_M24(_c_A2(11)) . _c_M25(_c_A2(12)) . _c_M26(_c_A2(13)) .
288             _c_M27(_c_A2(14)) . _c_M28(_c_A2(15)) . _c_M21(_c_A2( 0)) .
289             _c_M22(_c_A2( 1)) . _c_M23(_c_A2( 2)) . _c_M24(_c_A2( 3)) .
290             _c_M25(_c_A2( 4)) . _c_M26(_c_A2( 5)) . _c_M27(_c_A2( 6)) .
291             _c_M28(_c_A2( 7)) . _c_M21(_c_A2( 8)) . _c_M22(_c_A2( 9)) .
292             _c_M23(_c_A2(10)) . _c_M24(_c_A2(11)) . _c_M25(_c_A2(12)) .
293             _c_M26(_c_A2(13)) . _c_M27(_c_A2(14)) . _c_M28(_c_A2(15)) .
294              
295             ' $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
296             $self->{H}->[3] += $d; $self->{H}->[4] += $e; $self->{H}->[5] += $f;
297             $self->{H}->[6] += $g; $self->{H}->[7] += $h;
298             }
299             ';
300              
301 257     257   1035 eval($sha256_code);
  257         505  
  257         804  
  257         438  
  257         644  
  257         899  
  257         663  
  257         376  
  257         657  
  257         602  
  257         359  
  257         671  
  257         596  
  257         341  
  257         622  
  257         595  
  257         357  
  257         636  
  257         636  
  257         350  
  257         639  
  257         626  
  257         360  
  257         651  
  257         619  
  257         384  
  257         637  
  257         590  
  257         364  
  257         662  
  257         588  
  257         371  
  257         604  
  257         626  
  257         430  
  257         633  
  257         585  
  257         357  
  257         615  
  257         610  
  257         393  
  257         654  
  257         553  
  257         380  
  257         643  
  257         587  
  257         363  
  257         640  
  257         600  
  257         386  
  257         652  
  257         600  
  257         350  
  257         905  
  257         611  
  257         369  
  257         1013  
  257         651  
  257         360  
  257         910  
  257         609  
  257         387  
  257         954  
  257         626  
  257         398  
  257         907  
  257         582  
  257         377  
  257         936  
  257         971  
  257         362  
  257         985  
  257         594  
  257         349  
  257         912  
  257         664  
  257         366  
  257         928  
  257         620  
  257         392  
  257         983  
  257         605  
  257         359  
  257         925  
  257         608  
  257         344  
  257         924  
  257         588  
  257         345  
  257         1045  
  257         592  
  257         380  
  257         924  
  257         594  
  257         357  
  257         910  
  257         591  
  257         366  
  257         927  
  257         596  
  257         364  
  257         981  
  257         593  
  257         362  
  257         892  
  257         591  
  257         412  
  257         931  
  257         619  
  257         375  
  257         950  
  257         586  
  257         379  
  257         887  
  257         613  
  257         352  
  257         927  
  257         590  
  257         348  
  257         950  
  257         587  
  257         360  
  257         932  
  257         597  
  257         351  
  257         946  
  257         588  
  257         369  
  257         937  
  257         623  
  257         374  
  257         989  
  257         587  
  257         368  
  257         942  
  257         568  
  257         363  
  257         1248  
  257         725  
  257         349  
  257         941  
  257         602  
  257         367  
  257         860  
  257         611  
  257         378  
  257         891  
  257         580  
  257         365  
  257         971  
  257         597  
  257         353  
  257         903  
  257         587  
  257         372  
  257         912  
  257         547  
  257         350  
  257         1092  
  257         609  
  257         351  
  257         930  
  257         601  
  257         341  
  257         892  
  257         577  
  257         375  
  257         919  
  257         601  
  257         366  
  257         980  
  257         590  
  257         353  
  257         905  
  257         621  
  257         342  
  257         953  
  257         575  
  257         366  
  257         1054  
  257         582  
  257         359  
  257         945  
  257         583  
  257         363  
  257         884  
  257         550  
  257         350  
  257         975  
  257         583  
  257         349  
  257         896  
  257         606  
  257         356  
  257         869  
  257         569  
  257         350  
  257         483  
  257         411  
  257         389  
  257         363  
  257         363  
  257         374  
  257         374  
  257         1538  
302              
303 0     0   0 sub _sha512_placeholder { return }
304             my $sha512 = \&_sha512_placeholder;
305              
306             my $_64bit_code = '
307              
308             no warnings qw(portable);
309              
310             my @K512 = (
311             0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
312             0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
313             0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
314             0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
315             0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
316             0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
317             0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
318             0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
319             0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
320             0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
321             0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
322             0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
323             0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
324             0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
325             0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
326             0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
327             0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
328             0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
329             0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
330             0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
331             0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
332             0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
333             0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
334             0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
335             0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
336             0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
337             0x5fcb6fab3ad6faec, 0x6c44198c4a475817);
338              
339             @H0384 = (
340             0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17,
341             0x152fecd8f70e5939, 0x67332667ffc00b31, 0x8eb44a8768581511,
342             0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4);
343              
344             @H0512 = (
345             0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
346             0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
347             0x1f83d9abfb41bd6b, 0x5be0cd19137e2179);
348              
349             @H0512224 = (
350             0x8c3d37c819544da2, 0x73e1996689dcd4d6, 0x1dfab7ae32ff9c82,
351             0x679dd514582f9fcf, 0x0f6d2b697bd44da8, 0x77e36f7304c48942,
352             0x3f9d85a86a1d36c8, 0x1112e6ad91d692a1);
353              
354             @H0512256 = (
355             0x22312194fc2bf72c, 0x9f555fa3c84c64c2, 0x2393b86b6f53b151,
356             0x963877195940eabd, 0x96283ee2a88effe3, 0xbe5e1e2553863992,
357             0x2b0199fc2c85b8aa, 0x0eb72ddc81c52ca2);
358              
359             use warnings;
360              
361             sub _c_SL64 { my($x, $n) = @_; "($x << $n)" }
362              
363             sub _c_SR64 {
364             my($x, $n) = @_;
365             my $mask = (1 << (64 - $n)) - 1;
366             "(($x >> $n) & $mask)";
367             }
368              
369             sub _c_ROTRQ {
370             my($x, $n) = @_;
371             "(" . _c_SR64($x, $n) . " | " . _c_SL64($x, 64 - $n) . ")";
372             }
373              
374             sub _c_SIGMAQ0 {
375             my($x) = @_;
376             "(" . _c_ROTRQ($x, 28) . " ^ " . _c_ROTRQ($x, 34) . " ^ " .
377             _c_ROTRQ($x, 39) . ")";
378             }
379              
380             sub _c_SIGMAQ1 {
381             my($x) = @_;
382             "(" . _c_ROTRQ($x, 14) . " ^ " . _c_ROTRQ($x, 18) . " ^ " .
383             _c_ROTRQ($x, 41) . ")";
384             }
385              
386             sub _c_sigmaQ0 {
387             my($x) = @_;
388             "(" . _c_ROTRQ($x, 1) . " ^ " . _c_ROTRQ($x, 8) . " ^ " .
389             _c_SR64($x, 7) . ")";
390             }
391              
392             sub _c_sigmaQ1 {
393             my($x) = @_;
394             "(" . _c_ROTRQ($x, 19) . " ^ " . _c_ROTRQ($x, 61) . " ^ " .
395             _c_SR64($x, 6) . ")";
396             }
397              
398             my $sha512_code = q/
399             sub _sha512 {
400             my($self, $block) = @_;
401             my(@N, @W, $a, $b, $c, $d, $e, $f, $g, $h, $T1, $T2);
402              
403             @N = unpack("N32", $block);
404             ($a, $b, $c, $d, $e, $f, $g, $h) = @{$self->{H}};
405             for ( 0 .. 15) { $W[$_] = (($N[2*$_] << 16) << 16) | $N[2*$_+1] }
406             for (16 .. 79) { $W[$_] = / .
407             _c_sigmaQ1(q/$W[$_- 2]/) . q/ + $W[$_- 7] + / .
408             _c_sigmaQ0(q/$W[$_-15]/) . q/ + $W[$_-16] }
409             for ( 0 .. 79) {
410             $T1 = $h + / . _c_SIGMAQ1(q/$e/) .
411             q/ + (($g) ^ (($e) & (($f) ^ ($g)))) +
412             $K512[$_] + $W[$_];
413             $T2 = / . _c_SIGMAQ0(q/$a/) .
414             q/ + ((($a) & ($b)) | (($c) & (($a) | ($b))));
415             $h = $g; $g = $f; $f = $e; $e = $d + $T1;
416             $d = $c; $c = $b; $b = $a; $a = $T1 + $T2;
417             }
418             $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
419             $self->{H}->[3] += $d; $self->{H}->[4] += $e; $self->{H}->[5] += $f;
420             $self->{H}->[6] += $g; $self->{H}->[7] += $h;
421             }
422             /;
423              
424             eval($sha512_code);
425             $sha512 = \&_sha512;
426              
427             ';
428              
429 24     24   213 eval($_64bit_code) if $uses64bit;
  24     24   54  
  24     240   3042  
  24     24   158  
  24     24   49  
  24     240   8615  
  240     288   414  
  240     24   426  
  24     24   59  
  24     249   55  
  24         53  
  24         84  
  240         410  
  240         1007  
  288         455  
  288         450  
  288         1069  
  24         61  
  24         55  
  24         67  
  24         58  
  249         967  
  249         534  
  249         945  
  249         432  
  249         614  
  249         634  
  3984         7196  
  249         542  
  15936         44637  
  249         566  
  19920         41851  
  19920         38967  
  19920         27797  
  19920         27871  
  19920         27540  
  19920         27077  
  19920         27612  
  19920         27263  
  19920         27356  
  19920         29781  
  249         506  
  249         385  
  249         408  
  249         393  
  249         386  
  249         400  
  249         378  
  249         1897  
430              
431             sub _SETBIT {
432 190     190   371 my($self, $pos) = @_;
433 190         857 my @c = unpack("C*", $self->{block});
434 190 100       643 $c[$pos >> 3] = 0x00 unless defined $c[$pos >> 3];
435 190         450 $c[$pos >> 3] |= (0x01 << (7 - $pos % 8));
436 190         805 $self->{block} = pack("C*", @c);
437             }
438              
439             sub _CLRBIT {
440 80088     80088   117643 my($self, $pos) = @_;
441 80088         237059 my @c = unpack("C*", $self->{block});
442 80088 100       155062 $c[$pos >> 3] = 0x00 unless defined $c[$pos >> 3];
443 80088         118995 $c[$pos >> 3] &= ~(0x01 << (7 - $pos % 8));
444 80088         308688 $self->{block} = pack("C*", @c);
445             }
446              
447             sub _BYTECNT {
448 1783     1783   2668 my($bitcnt) = @_;
449 1783 100       4669 $bitcnt > 0 ? 1 + (($bitcnt - 1) >> 3) : 0;
450             }
451              
452             sub _digcpy {
453 190     190   334 my($self) = @_;
454 190         293 my @dig;
455 190         296 for (@{$self->{H}}) {
  190         570  
456 1520 100       2869 push(@dig, (($_>>16)>>16) & $MAX32) if $self->{alg} >= 384;
457 1520         2295 push(@dig, $_ & $MAX32);
458             }
459 190         1093 $self->{digest} = pack("N" . ($self->{digestlen}>>2), @dig);
460             }
461              
462             sub _sharewind {
463 217     217   397 my($self) = @_;
464 217         376 my $alg = $self->{alg};
465 217         404 $self->{block} = ""; $self->{blockcnt} = 0;
  217         339  
466 217 100       539 $self->{blocksize} = $alg <= 256 ? 512 : 1024;
467 217         444 for (qw(lenll lenlh lenhl lenhh)) { $self->{$_} = 0 }
  868         1585  
468 217 100       571 $self->{digestlen} = $alg == 1 ? 20 : ($alg % 1000)/8;
469 217 100       646 if ($alg == 1) { $self->{sha} = \&_sha1; $self->{H} = [@H01] }
  103 100       238  
  103 100       366  
    100          
    100          
    100          
    50          
470 4         13 elsif ($alg == 224) { $self->{sha} = \&_sha256; $self->{H} = [@H0224] }
  4         14  
471 53         115 elsif ($alg == 256) { $self->{sha} = \&_sha256; $self->{H} = [@H0256] }
  53         132  
472 27         52 elsif ($alg == 384) { $self->{sha} = $sha512; $self->{H} = [@H0384] }
  27         69  
473 26         46 elsif ($alg == 512) { $self->{sha} = $sha512; $self->{H} = [@H0512] }
  26         67  
474 2         3 elsif ($alg == 512224) { $self->{sha}=$sha512; $self->{H}=[@H0512224] }
  2         7  
475 2         5 elsif ($alg == 512256) { $self->{sha}=$sha512; $self->{H}=[@H0512256] }
  2         9  
476 217         351 push(@{$self->{H}}, 0) while scalar(@{$self->{H}}) < 8;
  526         1117  
  309         592  
477 217         1356 $self;
478             }
479              
480             sub _shaopen {
481 154     154   315 my($alg) = @_;
482 154         232 my($self);
483 154 100       328 return unless grep { $alg == $_ } (1,224,256,384,512,512224,512256);
  1078         2047  
484 153 50 66     538 return if ($alg >= 384 && !$uses64bit);
485 153         357 $self->{alg} = $alg;
486 153         340 _sharewind($self);
487             }
488              
489             sub _shadirect {
490 616     616   1194 my($bitstr, $bitcnt, $self) = @_;
491 616         878 my $savecnt = $bitcnt;
492 616         866 my $offset = 0;
493 616         999 my $blockbytes = $self->{blocksize} >> 3;
494 616         1514 while ($bitcnt >= $self->{blocksize}) {
495 836         1820 &{$self->{sha}}($self, substr($bitstr, $offset, $blockbytes));
  836         21264  
496 836         1883 $offset += $blockbytes;
497 836         2254 $bitcnt -= $self->{blocksize};
498             }
499 616 100       1262 if ($bitcnt > 0) {
500 525         1144 $self->{block} = substr($bitstr, $offset, _BYTECNT($bitcnt));
501 525         979 $self->{blockcnt} = $bitcnt;
502             }
503 616         2416 $savecnt;
504             }
505              
506             sub _shabytes {
507 656     656   1165 my($bitstr, $bitcnt, $self) = @_;
508 656         860 my($numbits);
509 656         858 my $savecnt = $bitcnt;
510 656 100       1254 if ($self->{blockcnt} + $bitcnt >= $self->{blocksize}) {
511 369         545 $numbits = $self->{blocksize} - $self->{blockcnt};
512 369         737 $self->{block} .= substr($bitstr, 0, $numbits >> 3);
513 369         498 $bitcnt -= $numbits;
514 369         603 $bitstr = substr($bitstr, $numbits >> 3, _BYTECNT($bitcnt));
515 369         614 &{$self->{sha}}($self, $self->{block});
  369         9301  
516 369         789 $self->{block} = "";
517 369         545 $self->{blockcnt} = 0;
518 369         814 _shadirect($bitstr, $bitcnt, $self);
519             }
520             else {
521 287         484 $self->{block} .= substr($bitstr, 0, _BYTECNT($bitcnt));
522 287         464 $self->{blockcnt} += $bitcnt;
523             }
524 656         1017 $savecnt;
525             }
526              
527             sub _shabits {
528 591     591   914 my($bitstr, $bitcnt, $self) = @_;
529 591         831 my($i, @buf);
530 591         878 my $numbytes = _BYTECNT($bitcnt);
531 591         2394 my $savecnt = $bitcnt;
532 591         969 my $gap = 8 - $self->{blockcnt} % 8;
533 591         1926 my @c = unpack("C*", $self->{block});
534 591         2255 my @b = unpack("C" . $numbytes, $bitstr);
535 591         1199 $c[$self->{blockcnt}>>3] &= (~0 << $gap);
536 591         1004 $c[$self->{blockcnt}>>3] |= $b[0] >> (8 - $gap);
537 591         1589 $self->{block} = pack("C*", @c);
538 591 100       1066 $self->{blockcnt} += ($bitcnt < $gap) ? $bitcnt : $gap;
539 591 100       1101 return($savecnt) if $bitcnt < $gap;
540 582 100       1082 if ($self->{blockcnt} == $self->{blocksize}) {
541 11         24 &{$self->{sha}}($self, $self->{block});
  11         284  
542 11         27 $self->{block} = "";
543 11         25 $self->{blockcnt} = 0;
544             }
545 582 100       1011 return($savecnt) if ($bitcnt -= $gap) == 0;
546 579         1142 for ($i = 0; $i < $numbytes - 1; $i++) {
547 27525         50955 $buf[$i] = (($b[$i] << $gap) & 0xff) | ($b[$i+1] >> (8 - $gap));
548             }
549 579         943 $buf[$numbytes-1] = ($b[$numbytes-1] << $gap) & 0xff;
550 579         1983 _shabytes(pack("C*", @buf), $bitcnt, $self);
551 579         2418 $savecnt;
552             }
553              
554             sub _shawrite {
555 916     916   1575 my($bitstr, $bitcnt, $self) = @_;
556 916 100       1742 return(0) unless $bitcnt > 0;
557 24     24   233 no integer;
  24         51  
  24         134  
558 915         1253 my $TWO32 = 4294967296;
559 915 100       2001 if (($self->{lenll} += $bitcnt) >= $TWO32) {
560 5         13 $self->{lenll} -= $TWO32;
561 5 50       15 if (++$self->{lenlh} >= $TWO32) {
562 0         0 $self->{lenlh} -= $TWO32;
563 0 0       0 if (++$self->{lenhl} >= $TWO32) {
564 0         0 $self->{lenhl} -= $TWO32;
565 0 0       0 if (++$self->{lenhh} >= $TWO32) {
566 0         0 $self->{lenhh} -= $TWO32;
567             }
568             }
569             }
570             }
571 24     24   2328 use integer;
  24         72  
  24         98  
572 915         1309 my $blockcnt = $self->{blockcnt};
573 915 100       1895 return(_shadirect($bitstr, $bitcnt, $self)) if $blockcnt == 0;
574 668 100       1370 return(_shabytes ($bitstr, $bitcnt, $self)) if $blockcnt % 8 == 0;
575 591         1024 return(_shabits ($bitstr, $bitcnt, $self));
576             }
577              
578             my $no_downgrade = 'sub utf8::downgrade { 1 }';
579              
580             my $pp_downgrade = q {
581             sub utf8::downgrade {
582              
583             # No need to downgrade if character and byte
584             # semantics are equivalent. But this might
585             # leave the UTF-8 flag set, harmlessly.
586              
587             require bytes;
588             return 1 if length($_[0]) == bytes::length($_[0]);
589              
590             use utf8;
591             return 0 if $_[0] =~ /[^\x00-\xff]/;
592             $_[0] = pack('C*', unpack('U*', $_[0]));
593             return 1;
594             }
595             };
596              
597             {
598 24     24   3316 no integer;
  24         52  
  24         83  
599              
600             if ($] < 5.006) { eval $no_downgrade }
601             elsif ($] < 5.008) { eval $pp_downgrade }
602             }
603              
604             my $WSE = 'Wide character in subroutine entry';
605             my $MWS = 16384;
606              
607             sub _shaWrite {
608 98     98   256 my($bytestr_r, $bytecnt, $self) = @_;
609 98 100       472 return(0) unless $bytecnt > 0;
610 86 100       600 croak $WSE unless utf8::downgrade($$bytestr_r, 1);
611 85 50       311 return(_shawrite($$bytestr_r, $bytecnt<<3, $self)) if $bytecnt <= $MWS;
612 0         0 my $offset = 0;
613 0         0 while ($bytecnt > $MWS) {
614 0         0 _shawrite(substr($$bytestr_r, $offset, $MWS), $MWS<<3, $self);
615 0         0 $offset += $MWS;
616 0         0 $bytecnt -= $MWS;
617             }
618 0         0 _shawrite(substr($$bytestr_r, $offset, $bytecnt), $bytecnt<<3, $self);
619             }
620              
621             sub _shafinish {
622 190     190   376 my($self) = @_;
623 190 100       520 my $LENPOS = $self->{alg} <= 256 ? 448 : 896;
624 190         596 _SETBIT($self, $self->{blockcnt}++);
625 190         505 while ($self->{blockcnt} > $LENPOS) {
626 1223 100       2116 if ($self->{blockcnt} < $self->{blocksize}) {
627 1202         1940 _CLRBIT($self, $self->{blockcnt}++);
628             }
629             else {
630 21         64 &{$self->{sha}}($self, $self->{block});
  21         667  
631 21         63 $self->{block} = "";
632 21         71 $self->{blockcnt} = 0;
633             }
634             }
635 190         456 while ($self->{blockcnt} < $LENPOS) {
636 78886         130641 _CLRBIT($self, $self->{blockcnt}++);
637             }
638 190 100       555 if ($self->{blocksize} > 512) {
639 53         172 $self->{block} .= pack("N", $self->{lenhh} & $MAX32);
640 53         143 $self->{block} .= pack("N", $self->{lenhl} & $MAX32);
641             }
642 190         523 $self->{block} .= pack("N", $self->{lenlh} & $MAX32);
643 190         425 $self->{block} .= pack("N", $self->{lenll} & $MAX32);
644 190         322 &{$self->{sha}}($self, $self->{block});
  190         5799  
645             }
646              
647 79     79   152 sub _shadigest { my($self) = @_; _digcpy($self); $self->{digest} }
  79         221  
  79         489  
648              
649             sub _shahex {
650 100     100   230 my($self) = @_;
651 100         328 _digcpy($self);
652 100         759 join("", unpack("H*", $self->{digest}));
653             }
654              
655             sub _shabase64 {
656 11     11   25 my($self) = @_;
657 11         38 _digcpy($self);
658 11         52 my $b64 = pack("u", $self->{digest});
659 11         55 $b64 =~ s/^.//mg;
660 11         40 $b64 =~ s/\n//g;
661 11         32 $b64 =~ tr|` -_|AA-Za-z0-9+/|;
662 11         28 my $numpads = (3 - length($self->{digest}) % 3) % 3;
663 11 100       93 $b64 =~ s/.{$numpads}$// if $numpads;
664 11         57 $b64;
665             }
666              
667 0     0   0 sub _shadsize { my($self) = @_; $self->{digestlen} }
  0         0  
668              
669             sub _shacpy {
670 17     17   43 my($to, $from) = @_;
671 17         62 $to->{alg} = $from->{alg};
672 17         38 $to->{sha} = $from->{sha};
673 17         26 $to->{H} = [@{$from->{H}}];
  17         45  
674 17         39 $to->{block} = $from->{block};
675 17         66 $to->{blockcnt} = $from->{blockcnt};
676 17         29 $to->{blocksize} = $from->{blocksize};
677 17         38 for (qw(lenhh lenhl lenlh lenll)) { $to->{$_} = $from->{$_} }
  68         150  
678 17         33 $to->{digestlen} = $from->{digestlen};
679 17         90 $to;
680             }
681              
682 11     11   22 sub _shadup { my($self) = @_; my($copy); _shacpy($copy, $self) }
  11         14  
  11         30  
683              
684             sub _shadump {
685 4     4   10 my $self = shift;
686 4         16 for (qw(alg H block blockcnt lenhh lenhl lenlh lenll)) {
687 32 50       80 return unless defined $self->{$_};
688             }
689              
690 4         20 my @state = ();
691 4 100       27 my $fmt = ($self->{alg} <= 256 ? "%08x" : "%016x");
692              
693 4         21 push(@state, "alg:" . $self->{alg});
694              
695 4 100       10 my @H = map { $self->{alg} <= 256 ? $_ & $MAX32 : $_ } @{$self->{H}};
  32         85  
  4         19  
696 4         16 push(@state, "H:" . join(":", map { sprintf($fmt, $_) } @H));
  32         112  
697              
698 4         30 my @c = unpack("C*", $self->{block});
699 4         102 push(@c, 0x00) while scalar(@c) < ($self->{blocksize} >> 3);
700 4         15 push(@state, "block:" . join(":", map {sprintf("%02x", $_)} @c));
  384         731  
701 4         32 push(@state, "blockcnt:" . $self->{blockcnt});
702              
703 4         10 push(@state, "lenhh:" . $self->{lenhh});
704 4         10 push(@state, "lenhl:" . $self->{lenhl});
705 4         17 push(@state, "lenlh:" . $self->{lenlh});
706 4         14 push(@state, "lenll:" . $self->{lenll});
707 4         40 join("\n", @state) . "\n";
708             }
709              
710             sub _shaload {
711 11     11   27 my $state = shift;
712              
713 11         31 my %s = ();
714 11         92 for (split(/\n/, $state)) {
715 96         197 s/^\s+//;
716 96         184 s/\s+$//;
717 96 100       230 next if (/^(#|$)/);
718 88         702 my @f = split(/[:\s]+/);
719 88         179 my $tag = shift(@f);
720 88         361 $s{$tag} = join('', @f);
721             }
722              
723             # H and block may contain arbitrary values, but check everything else
724 11 50       34 grep { $_ == $s{alg} } (1,224,256,384,512,512224,512256) or return;
  77         173  
725 11 100       91 length($s{H}) == ($s{alg} <= 256 ? 64 : 128) or return;
    50          
726 11 100       50 length($s{block}) == ($s{alg} <= 256 ? 128 : 256) or return;
    50          
727             {
728 24     24   33593 no integer;
  24         68  
  24         134  
  11         18  
729 11         28 for (qw(blockcnt lenhh lenhl lenlh lenll)) {
730 55 50       141 0 <= $s{$_} or return;
731 55 50       124 $s{$_} <= 4294967295 or return;
732             }
733 11 100       45 $s{blockcnt} < ($s{alg} <= 256 ? 512 : 1024) or return;
    50          
734             }
735              
736 11 50       42 my $self = _shaopen($s{alg}) or return;
737              
738 11         140 my @h = $s{H} =~ /(.{8})/g;
739 11         25 for (@{$self->{H}}) {
  11         39  
740 88         150 $_ = hex(shift @h);
741 88 100       189 if ($self->{alg} > 256) {
742 32         119 $_ = (($_ << 16) << 16) | hex(shift @h);
743             }
744             }
745              
746 11         54 $self->{blockcnt} = $s{blockcnt};
747 11         89 $self->{block} = pack("H*", $s{block});
748 11         34 $self->{block} = substr($self->{block},0,_BYTECNT($self->{blockcnt}));
749              
750 11         29 $self->{lenhh} = $s{lenhh};
751 11         23 $self->{lenhl} = $s{lenhl};
752 11         19 $self->{lenlh} = $s{lenlh};
753 11         26 $self->{lenll} = $s{lenll};
754              
755 11         59 $self;
756             }
757              
758             # ref. src/hmac.c from Digest::SHA
759              
760             sub _hmacopen {
761 43     43   108 my($alg, $key) = @_;
762 43         72 my($self);
763 43 50       104 $self->{isha} = _shaopen($alg) or return;
764 43 50       94 $self->{osha} = _shaopen($alg) or return;
765 43 50       137 croak $WSE unless utf8::downgrade($key, 1);
766 43 100       126 if (length($key) > $self->{osha}->{blocksize} >> 3) {
767 11 50       40 $self->{ksha} = _shaopen($alg) or return;
768 11         40 _shawrite($key, length($key) << 3, $self->{ksha});
769 11         32 _shafinish($self->{ksha});
770 11         44 $key = _shadigest($self->{ksha});
771             }
772             $key .= chr(0x00)
773 43         1457 while length($key) < $self->{osha}->{blocksize} >> 3;
774 43         268 my @k = unpack("C*", $key);
775 43         98 for (@k) { $_ ^= 0x5c }
  3712         4739  
776 43         276 _shawrite(pack("C*", @k), $self->{osha}->{blocksize}, $self->{osha});
777 43         110 for (@k) { $_ ^= (0x5c ^ 0x36) }
  3712         4750  
778 43         265 _shawrite(pack("C*", @k), $self->{isha}->{blocksize}, $self->{isha});
779 43         1241 $self;
780             }
781              
782             sub _hmacWrite {
783 45     45   99 my($bytestr_r, $bytecnt, $self) = @_;
784 45         134 _shaWrite($bytestr_r, $bytecnt, $self->{isha});
785             }
786              
787             sub _hmacfinish {
788 43     43   83 my($self) = @_;
789 43         108 _shafinish($self->{isha});
790             _shawrite(_shadigest($self->{isha}),
791 43         118 $self->{isha}->{digestlen} << 3, $self->{osha});
792 43         114 _shafinish($self->{osha});
793             }
794              
795 23     23   48 sub _hmacdigest { my($self) = @_; _shadigest($self->{osha}) }
  23         47  
796 20     20   43 sub _hmachex { my($self) = @_; _shahex($self->{osha}) }
  20         44  
797 0     0   0 sub _hmacbase64 { my($self) = @_; _shabase64($self->{osha}) }
  0         0  
798              
799             # SHA and HMAC-SHA functions
800              
801             my @suffix_extern = ("", "_hex", "_base64");
802             my @suffix_intern = ("digest", "hex", "base64");
803              
804             my($i, $alg);
805             for $alg (1, 224, 256, 384, 512, 512224, 512256) {
806             for $i (0 .. 2) {
807             my $fcn = 'sub sha' . $alg . $suffix_extern[$i] . ' {
808             my $state = _shaopen(' . $alg . ') or return;
809             for (@_) { _shaWrite(\$_, length($_), $state) }
810             _shafinish($state);
811             _sha' . $suffix_intern[$i] . '($state);
812             }';
813 1 50   1 1 8 eval($fcn);
  1 50   2 1 4  
  1 50   5 1 11  
  1 0   0 1 10  
  1 50   2 1 11  
  2 50   2 1 262  
  2 0   0 1 6  
  2 50   2 1 8  
  2 50   2 1 10  
  2 0   0 1 19  
  5 50   2 1 404  
  5 50   4 1 19  
  5 0   0 1 27  
  4 0   0 1 24  
  4 0   0 1 21  
  0 50   2 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 50   2 1 0  
  0 50   2 1 0  
  2 50   5 1 63  
  2         7  
  2         8  
  2         7  
  2         8  
  2         249  
  2         6  
  2         8  
  2         9  
  2         9  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         58  
  2         10  
  2         8  
  2         8  
  2         10  
  2         232  
  2         8  
  2         45  
  2         9  
  2         14  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         66  
  2         8  
  2         8  
  2         7  
  2         9  
  4         345  
  4         14  
  4         22  
  4         21  
  4         24  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         75  
  2         7  
  2         7  
  2         7  
  2         8  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         76  
  2         11  
  2         9  
  2         28  
  2         8  
  2         60  
  2         7  
  2         20  
  2         10  
  2         24  
  5         654  
  5         23  
  5         34  
  5         32  
  5         28  
814             push(@EXPORT_OK, 'sha' . $alg . $suffix_extern[$i]);
815             $fcn = 'sub hmac_sha' . $alg . $suffix_extern[$i] . ' {
816             my $state = _hmacopen(' . $alg . ', pop(@_)) or return;
817             for (@_) { _hmacWrite(\$_, length($_), $state) }
818             _hmacfinish($state);
819             _hmac' . $suffix_intern[$i] . '($state);
820             }';
821 0 0   0 1 0 eval($fcn);
  0 0   0 1 0  
  0 50   11 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 50   8 1 0  
  0 0   0 1 0  
  0 50   9 1 0  
  0 50   8 1 0  
  11 0   0 1 905  
  11 0   0 1 174  
  11 50   7 1 43  
  11 0   0 1 40  
  11 0   0 1 46  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  8         2695  
  8         28  
  10         34  
  8         44  
  8         41  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  9         297  
  9         47  
  9         27  
  9         36  
  9         47  
  8         262  
  8         31  
  8         27  
  8         29  
  8         36  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  7         234  
  7         23  
  7         28  
  7         28  
  7         41  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
822             push(@EXPORT_OK, 'hmac_sha' . $alg . $suffix_extern[$i]);
823             }
824             }
825              
826             # OOP methods
827              
828 0     0 1 0 sub hashsize { my $self = shift; _shadsize($self) << 3 }
  0         0  
829 4     4 1 9 sub algorithm { my $self = shift; $self->{alg} }
  4         30  
830              
831             sub add {
832 19     19 1 553 my $self = shift;
833 19         54 for (@_) { _shaWrite(\$_, length($_), $self) }
  20         54  
834 19         63 $self;
835             }
836              
837             sub digest {
838 1     1 1 3 my $self = shift;
839 1         10 _shafinish($self);
840 1         8 my $rsp = _shadigest($self);
841 1         5 _sharewind($self);
842 1         31 $rsp;
843             }
844              
845             sub hexdigest {
846 59     59 1 233 my $self = shift;
847 59         166 _shafinish($self);
848 59         196 my $rsp = _shahex($self);
849 59         182 _sharewind($self);
850 59         181 $rsp;
851             }
852              
853             sub b64digest {
854 1     1 1 4 my $self = shift;
855 1         5 _shafinish($self);
856 1         6 my $rsp = _shabase64($self);
857 1         6 _sharewind($self);
858 1         3 $rsp;
859             }
860              
861             sub new {
862 16     16 1 1618 my($class, $alg) = @_;
863 16 100       125 $alg =~ s/\D+//g if defined $alg;
864 16 100       62 if (ref($class)) { # instance method
865 5 100 100     24 if (!defined($alg) || ($alg == $class->algorithm)) {
866 3         10 _sharewind($class);
867 3         17 return($class);
868             }
869 2 50       11 my $self = _shaopen($alg) or return;
870 2         9 return(_shacpy($class, $self));
871             }
872 11 100       41 $alg = 1 unless defined $alg;
873 11 100       41 my $self = _shaopen($alg) or return;
874 10         34 bless($self, $class);
875 10         52 $self;
876             }
877              
878             sub clone {
879 11     11 1 320 my $self = shift;
880 11 50       26 my $copy = _shadup($self) or return;
881 11         48 bless($copy, ref($self));
882             }
883              
884 24     24   60759 BEGIN { *reset = \&new }
885              
886             sub add_bits {
887 691     691 1 3275 my($self, $data, $nbits) = @_;
888 691 100       1418 unless (defined $nbits) {
889 38         62 $nbits = length($data);
890 38         154 $data = pack("B*", $data);
891             }
892 691 50       1351 $nbits = length($data) * 8 if $nbits > length($data) * 8;
893 691         1525 _shawrite($data, $nbits, $self);
894 691         1383 return($self);
895             }
896              
897             sub _bail {
898 0     0   0 my $msg = shift;
899              
900 0         0 $errmsg = $!;
901 0         0 $msg .= ": $!";
902 0         0 croak $msg;
903             }
904              
905             sub _addfile {
906 3     3   7 my ($self, $handle) = @_;
907              
908 3         6 my $n;
909 3         4 my $buf = "";
910              
911 3         101 while (($n = read($handle, $buf, 4096))) {
912 3         12 $self->add($buf);
913             }
914 3 50       15 _bail("Read failed") unless defined $n;
915              
916 3         11 $self;
917             }
918              
919             {
920             my $_can_T_filehandle;
921              
922             sub _istext {
923 1     1   3 local *FH = shift;
924 1         3 my $file = shift;
925              
926 1 50       3 if (! defined $_can_T_filehandle) {
927 1         5 local $^W = 0;
928 1         3 my $istext = eval { -T FH };
  1         23  
929 1 50       8 $_can_T_filehandle = $@ ? 0 : 1;
930 1 50       17 return $_can_T_filehandle ? $istext : -T $file;
931             }
932 0 0       0 return $_can_T_filehandle ? -T FH : -T $file;
933             }
934             }
935              
936             sub addfile {
937 6     6 1 82 my ($self, $file, $mode) = @_;
938              
939 6 100       26 return(_addfile($self, $file)) unless ref(\$file) eq 'SCALAR';
940              
941 4 50       13 $mode = defined($mode) ? $mode : "";
942             my ($binary, $UNIVERSAL, $BITS) =
943 4         11 map { $_ eq $mode } ("b", "U", "0");
  12         35  
944              
945             ## Always interpret "-" to mean STDIN; otherwise use
946             ## sysopen to handle full range of POSIX file names.
947             ## If $file is a directory, force an EISDIR error
948             ## by attempting to open with mode O_RDWR
949              
950 4         19 local *FH;
951 4 50       12 if ($file eq '-') {
952 0 0       0 if (-d STDIN) {
953 0 0       0 sysopen(FH, getcwd(), O_RDWR)
954             or _bail('Open failed');
955             }
956 0 0       0 open(FH, '< -')
957             or _bail('Open failed');
958             }
959             else {
960 4 50       181 sysopen(FH, $file, -d $file ? O_RDWR : O_RDONLY)
    50          
961             or _bail('Open failed');
962             }
963              
964 4 100       22 if ($BITS) {
965 2         8 my ($n, $buf) = (0, "");
966 2         49 while (($n = read(FH, $buf, 4096))) {
967 2         8 $buf =~ tr/01//cd;
968 2         8 $self->add_bits($buf);
969             }
970 2 50       7 _bail("Read failed") unless defined $n;
971 2         21 close(FH);
972 2         14 return($self);
973             }
974              
975 2 50 66     13 binmode(FH) if $binary || $UNIVERSAL;
976 2 100 66     11 if ($UNIVERSAL && _istext(*FH, $file)) {
977 1         18 while () {
978 3         12 s/\015\012/\012/g; # DOS/Windows
979 3         7 s/\015/\012/g; # early MacOS
980 3         8 $self->add($_);
981             }
982             }
983 1         5 else { $self->_addfile(*FH) }
984 2         22 close(FH);
985              
986 2         25 $self;
987             }
988              
989             sub getstate {
990 4     4 1 11 my $self = shift;
991              
992 4         37 return _shadump($self);
993             }
994              
995             sub putstate {
996 11     11 1 1542 my $class = shift;
997 11         26 my $state = shift;
998              
999 11 100       41 if (ref($class)) { # instance method
1000 4 50       14 my $self = _shaload($state) or return;
1001 4         25 return(_shacpy($class, $self));
1002             }
1003 7 50       25 my $self = _shaload($state) or return;
1004 7         28 bless($self, $class);
1005 7         54 return($self);
1006             }
1007              
1008             sub dump {
1009 0     0 1   my $self = shift;
1010 0           my $file = shift;
1011              
1012 0 0         my $state = $self->getstate or return;
1013 0 0 0       $file = "-" if (!defined($file) || $file eq "");
1014              
1015 0           local *FH;
1016 0 0         open(FH, "> $file") or return;
1017 0           print FH $state;
1018 0           close(FH);
1019              
1020 0           return($self);
1021             }
1022              
1023             sub load {
1024 0     0 1   my $class = shift;
1025 0           my $file = shift;
1026              
1027 0 0 0       $file = "-" if (!defined($file) || $file eq "");
1028            
1029 0           local *FH;
1030 0 0         open(FH, "< $file") or return;
1031 0           my $str = join('', );
1032 0           close(FH);
1033              
1034 0           $class->putstate($str);
1035             }
1036              
1037             1;
1038             __END__