Remove unused pkg dependancy
[platform/upstream/iotivity.git] / extlibs / tinydtls / sha2 / sha2test.pl
1 #!/usr/bin/perl
2 #
3 # FILE:         sha2test.pl
4 # AUTHOR:       Aaron D. Gifford - http://www.aarongifford.com/
5
6 # Copyright (c) 2001, Aaron D. Gifford
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions
11 # are met:
12 # 1. Redistributions of source code must retain the above copyright
13 #    notice, this list of conditions and the following disclaimer.
14 # 2. Redistributions in binary form must reproduce the above copyright
15 #    notice, this list of conditions and the following disclaimer in the
16 #    documentation and/or other materials provided with the distribution.
17 # 3. Neither the name of the copyright holder nor the names of contributors
18 #    may be used to endorse or promote products derived from this software
19 #    without specific prior written permission.
20
21 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
22 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
25 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # SUCH DAMAGE.
32 #
33 # $Id: sha2test.pl,v 1.1 2001/11/08 00:02:37 adg Exp adg $
34 #
35
36 sub usage {
37         my ($err) = shift(@_);
38
39         print <<EOM;
40 Error:
41         $err
42 Usage:
43         $0 [<options>] [<test-vector-info-file> [<test-vector-info-file> ...]]
44
45 Options:
46         -256    Use SHA-256 hashes during testing
47         -384    Use SHA-384 hashes during testing
48         -512    Use SHA-512 hashes during testing
49         -ALL    Use all three hashes during testing
50         -c256 <command-spec>    Specify a command to execute to generate a
51                                 SHA-256 hash.  Be sure to include a '%'
52                                 character which will be replaced by the
53                                 test vector data filename containing the
54                                 data to be hashed.  This command implies
55                                 the -256 option.
56         -c384 <command-spec>    Specify a command to execute to generate a
57                                 SHA-384 hash.  See above.  Implies -384.
58         -c512 <command-spec>    Specify a command to execute to generate a
59                                 SHA-512 hash.  See above.  Implies -512.
60         -cALL <command-spec>    Specify a command to execute that will
61                                 generate all three hashes at once and output
62                                 the data in hexadecimal.  See above for
63                                 information about the <command-spec>.
64                                 This option implies the -ALL option, and
65                                 also overrides any other command options if
66                                 present.
67
68 By default, this program expects to execute the command ./sha2 within the
69 current working directory to generate all hashes.  If no test vector
70 information files are specified, this program expects to read a series of
71 files ending in ".info" within a subdirectory of the current working
72 directory called "testvectors".
73
74 EOM
75         exit(-1);
76 }
77
78 $c256 = $c384 = $c512 = $cALL = "";
79 $hashes = 0;
80 @FILES = ();
81
82 # Read all command-line options and files:
83 while ($opt = shift(@ARGV)) {
84         if ($opt =~ s/^\-//) {
85                 if ($opt eq "256") {
86                         $hashes |= 1;
87                 } elsif ($opt eq "384") {
88                         $hashes |= 2;
89                 } elsif ($opt eq "512") {
90                         $hashes |= 4;
91                 } elsif ($opt =~ /^ALL$/i) {
92                         $hashes = 7;
93                 } elsif ($opt =~ /^c256$/i) {
94                         $hashes |= 1;
95                         $opt = $c256 = shift(@ARGV);
96                         $opt =~ s/\s+.*$//;
97                         if (!$c256 || $c256 !~ /\%/ || !-x $opt) {
98                                 usage("Missing or invalid command specification for option -c256: $opt\n");
99                         }
100                 } elsif ($opt =~ /^c384$/i) {
101                         $hashes |= 2;
102                         $opt = $c384 = shift(@ARGV);
103                         $opt =~ s/\s+.*$//;
104                         if (!$c384 || $c384 !~ /\%/ || !-x $opt) {
105                                 usage("Missing or invalid command specification for option -c384: $opt\n");
106                         }
107                 } elsif ($opt =~ /^c512$/i) {
108                         $hashes |= 4;
109                         $opt = $c512 = shift(@ARGV);
110                         $opt =~ s/\s+.*$//;
111                         if (!$c512 || $c512 !~ /\%/ || !-x $opt) {
112                                 usage("Missing or invalid command specification for option -c512: $opt\n");
113                         }
114                 } elsif ($opt =~ /^cALL$/i) {
115                         $hashes = 7;
116                         $opt = $cALL = shift(@ARGV);
117                         $opt =~ s/\s+.*$//;
118                         if (!$cALL || $cALL !~ /\%/ || !-x $opt) {
119                                 usage("Missing or invalid command specification for option -cALL: $opt\n");
120                         }
121                 } else {
122                         usage("Unknown/invalid option '$opt'\n");
123                 }
124         } else {
125                 usage("Invalid, nonexistent, or unreadable file '$opt': $!\n") if (!-f $opt);
126                 push(@FILES, $opt);
127         }
128 }
129
130 # Set up defaults:
131 if (!$cALL && !$c256 && !$c384 && !$c512) {
132         $cALL = "./sha2 -ALL %";
133         usage("Required ./sha2 binary executable not found.\n") if (!-x "./sha2");
134 }
135 $hashes = 7 if (!$hashes);
136
137 # Do some sanity checks:
138 usage("No command was supplied to generate SHA-256 hashes.\n") if ($hashes & 1 == 1 && !$cALL && !$c256);
139 usage("No command was supplied to generate SHA-384 hashes.\n") if ($hashes & 2 == 2 && !$cALL && !$c384);
140 usage("No command was supplied to generate SHA-512 hashes.\n") if ($hashes & 4 == 4 && !$cALL && !$c512);
141
142 # Default .info files:
143 if (scalar(@FILES) < 1) {
144         opendir(DIR, "testvectors") || usage("Unable to scan directory 'testvectors' for vector information files: $!\n");
145         @FILES = grep(/\.info$/, readdir(DIR));
146         closedir(DIR);
147         @FILES = map { s/^/testvectors\//; $_; } @FILES;
148         @FILES = sort(@FILES);
149 }
150
151 # Now read in each test vector information file:
152 foreach $file (@FILES) {
153         $dir = $file;
154         if ($file !~ /\//) {
155                 $dir = "./";
156         } else {
157                 $dir =~ s/\/[^\/]+$//;
158                 $dir .= "/";
159         }
160         open(FILE, "<" . $file) ||
161                 usage("Unable to open test vector information file '$file' for reading: $!\n");
162         $vec = { desc => "", file => "", sha256 => "", sha384 => "", sha512 => "" };
163         $data = $field = "";
164         $line = 0;
165         while(<FILE>) {
166                 $line++;
167                 s/\s*[\r\n]+$//;
168                 next if ($field && $field ne "DESCRIPTION" && !$_);
169                 if (/^(DESCRIPTION|FILE|SHA256|SHA384|SHA512):$/) {
170                         if ($field eq "DESCRIPTION") {
171                                 $vec->{desc} = $data;
172                         } elsif ($field eq "FILE") {
173                                 $data = $dir . $data if ($data !~ /^\//);
174                                 $vec->{file} = $data;
175                         } elsif ($field eq "SHA256") {
176                                 $vec->{sha256} = $data;
177                         } elsif ($field eq "SHA384") {
178                                 $vec->{sha384} = $data;
179                         } elsif ($field eq "SHA512") {
180                                 $vec->{sha512} = $data;
181                         }
182                         $data = "";
183                         $field = $1;
184                 } elsif ($field eq "DESCRIPTION") {
185                         s/^    //;
186                         $data .= $_ . "\n";
187                 } elsif ($field =~ /^SHA\d\d\d$/) {
188                         s/^\s+//;
189                         if (!/^([a-f0-9]{32}|[a-f0-9]{64})$/) {
190                                 usage("Invalid SHA-256/384/512 test vector information " .
191                                       "file format at line $line of file '$file'\n");
192                         }
193                         $data .= $_;
194                 } elsif ($field eq "FILE") {
195                         s/^    //;
196                         $data .= $_;
197                 } else {
198                         usage("Invalid SHA-256/384/512 test vector information file " .
199                               "format at line $line of file '$file'\n");
200                 }
201         }
202         if ($field eq "DESCRIPTION") {
203                 $data = $dir . $data if ($data !~ /^\//);
204                 $vec->{desc} = $data;
205         } elsif ($field eq "FILE") {
206                 $vec->{file} = $data;
207         } elsif ($field eq "SHA256") {
208                 $vec->{sha256} = $data;
209         } elsif ($field eq "SHA384") {
210                 $vec->{sha384} = $data;
211         } elsif ($field eq "SHA512") {
212                 $vec->{sha512} = $data;
213         } else {
214                 usage("Invalid SHA-256/384/512 test vector information file " .
215                       "format.  Missing required fields in file '$file'\n");
216         }
217
218         # Sanity check all entries:
219         if (!$vec->{desc}) {
220                 usage("Invalid SHA-256/384/512 test vector information file " .
221                       "format.  Missing required DESCRIPTION field in file '$file'\n");
222         }
223         if (!$vec->{file}) {
224                 usage("Invalid SHA-256/384/512 test vector information file " .
225                       "format.  Missing required FILE field in file '$file'\n");
226         }
227         if (! -f $vec->{file}) {
228                 usage("The test vector data file (field FILE) name " .
229                       "'$vec->{file}' is not a readable file.  Check the FILE filed in " .
230                       "file '$file'.\n");
231         }
232         if (!($vec->{sha256} || $vec->{sha384} || $vec->{sha512})) {
233                 usage("Invalid SHA-256/384/512 test vector information file " .
234                       "format.  There must be at least one SHA256, SHA384, or SHA512 " .
235                       "field specified in file '$file'.\n");
236         }
237         if ($vec->{sha256} !~ /^(|[a-f0-9]{64})$/) {
238                 usage("Invalid SHA-256/384/512 test vector information file " .
239                       "format.  The SHA256 field is invalid in file '$file'.\n");
240         }
241         if ($vec->{sha384} !~ /^(|[a-f0-9]{96})$/) {
242                 usage("Invalid SHA-256/384/512 test vector information file " .
243                       "format.  The SHA384 field is invalid in file '$file'.\n");
244         }
245         if ($vec->{sha512} !~ /^(|[a-f0-9]{128})$/) {
246                 usage("Invalid SHA-256/384/512 test vector information file " .
247                       "format.  The SHA512 field is invalid in file '$file'.\n");
248         }
249         close(FILE);
250         if ($hashes & (($vec->{sha256} ? 1 : 0) | ($vec->{sha384} ? 2 : 0) | ($vec->{sha512} ? 4 : 0))) {
251                 push(@VECTORS, $vec);
252         }
253 }
254
255 usage("There were no test vectors for the specified hash(es) in any of the test vector information files you specified.\n") if (scalar(@VECTORS) < 1);
256
257 $num = $errors = $error256 = $error384 = $error512 = $tests = $test256 = $test384 = $test512 = 0;
258 foreach $vec (@VECTORS) {
259         $num++;
260         print "TEST VECTOR #$num:\n";
261         print "\t" . join("\n\t", split(/\n/, $vec->{desc})) . "\n";
262         print "VECTOR DATA FILE:\n\t$vec->{file}\n";
263         $sha256 = $sha384 = $sha512 = "";
264         if ($cALL) {
265                 $prog = $cALL;
266                 $prog =~ s/\%/'$vec->{file}'/g;
267                 @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`));
268                 ($sha256) = grep(/(^[a-fA-F0-9]{64}$|^[a-fA-F0-9]{64}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{64}$|[^a-fA-F0-9][a-fA-F0-9]{64}[^a-fA-F0-9])/, @SHA);
269                 ($sha384) = grep(/(^[a-fA-F0-9]{96}$|^[a-fA-F0-9]{96}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{96}$|[^a-fA-F0-9][a-fA-F0-9]{96}[^a-fA-F0-9])/, @SHA);
270                 ($sha512) = grep(/(^[a-fA-F0-9]{128}$|^[a-fA-F0-9]{128}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{128}$|[^a-fA-F0-9][a-fA-F0-9]{128}[^a-fA-F0-9])/, @SHA);
271         } else {
272                 if ($c256) {
273                         $prog = $c256;
274                         $prog =~ s/\%/'$vec->{file}'/g;
275                         @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`));
276                         ($sha256) = grep(/(^[a-fA-F0-9]{64}$|^[a-fA-F0-9]{64}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{64}$|[^a-fA-F0-9][a-fA-F0-9]{64}[^a-fA-F0-9])/, @SHA);
277                 }
278                 if ($c384) {
279                         $prog = $c384;
280                         $prog =~ s/\%/'$vec->{file}'/g;
281                         @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`));
282                         ($sha384) = grep(/(^[a-fA-F0-9]{96}$|^[a-fA-F0-9]{96}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{96}$|[^a-fA-F0-9][a-fA-F0-9]{96}[^a-fA-F0-9])/, @SHA);
283                 }
284                 if ($c512) {
285                         $prog = $c512;
286                         $prog =~ s/\%/'$vec->{file}'/g;
287                         @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`));
288                         ($sha512) = grep(/(^[a-fA-F0-9]{128}$|^[a-fA-F0-9]{128}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{128}$|[^a-fA-F0-9][a-fA-F0-9]{128}[^a-fA-F0-9])/, @SHA);
289                 }
290         }
291         usage("Unable to generate any hashes for file '$vec->{file}'!\n") if (!$sha256 && !$sha384 && $sha512);
292         $sha256 =~ tr/A-F/a-f/;
293         $sha384 =~ tr/A-F/a-f/;
294         $sha512 =~ tr/A-F/a-f/;
295         $sha256 =~ s/^.*([a-f0-9]{64}).*$/$1/;
296         $sha384 =~ s/^.*([a-f0-9]{96}).*$/$1/;
297         $sha512 =~ s/^.*([a-f0-9]{128}).*$/$1/;
298
299         if ($sha256 && $hashes & 1 == 1) {
300                 if ($vec->{sha256} eq $sha256) {
301                         print "SHA256 MATCHES:\n\t$sha256\n"
302                 } else {
303                         print "SHA256 DOES NOT MATCH:\n\tEXPECTED:\n\t\t$vec->{sha256}\n" .
304                               "\tGOT:\n\t\t$sha256\n\n";
305                         $error256++;
306                 }
307                 $test256++;
308         }
309         if ($sha384 && $hashes & 2 == 2) {
310                 if ($vec->{sha384} eq $sha384) {
311                         print "SHA384 MATCHES:\n\t" . substr($sha384, 0, 64) . "\n\t" .
312                               substr($sha384, -32) . "\n";
313                 } else {
314                         print "SHA384 DOES NOT MATCH:\n\tEXPECTED:\n\t\t" .
315                               substr($vec->{sha384}, 0, 64) . "\n\t\t" .
316                               substr($vec->{sha384}, -32) . "\n\tGOT:\n\t\t" .
317                               substr($sha384, 0, 64) . "\n\t\t" . substr($sha384, -32) . "\n\n";
318                         $error384++;
319                 }
320                 $test384++;
321         }
322         if ($sha512 && $hashes & 4 == 4) {
323                 if ($vec->{sha512} eq $sha512) {
324                         print "SHA512 MATCHES:\n\t" . substr($sha512, 0, 64) . "\n\t" .
325                               substr($sha512, -64) . "\n";
326                 } else {
327                         print "SHA512 DOES NOT MATCH:\n\tEXPECTED:\n\t\t" .
328                               substr($vec->{sha512}, 0, 64) . "\n\t\t" .
329                               substr($vec->{sha512}, -32) . "\n\tGOT:\n\t\t" .
330                               substr($sha512, 0, 64) . "\n\t\t" . substr($sha512, -64) . "\n\n";
331                         $error512++;
332                 }
333                 $test512++;
334         }
335 }
336
337 $errors = $error256 + $error384 + $error512;
338 $tests = $test256 + $test384 + $test512;
339 print "\n\n===== RESULTS ($num VECTOR DATA FILES HASHED) =====\n\n";
340 print "HASH TYPE\tNO. OF TESTS\tPASSED\tFAILED\n";
341 print "---------\t------------\t------\t------\n";
342 if ($test256) {
343         $pass = $test256 - $error256;
344         print "SHA-256\t\t".substr("           $test256", -12)."\t".substr("     $pass", -6)."\t".substr("     $error256", -6)."\n";
345 }
346 if ($test384) {
347         $pass = $test384 - $error384;
348         print "SHA-384\t\t".substr("           $test384", -12)."\t".substr("     $pass", -6)."\t".substr("     $error384", -6)."\n";
349 }
350 if ($test512) {
351         $pass = $test512 - $error512;
352         print "SHA-512\t\t".substr("           $test512", -12)."\t".substr("     $pass", -6)."\t".substr("     $error512", -6)."\n";
353 }
354 print "----------------------------------------------\n";
355 $pass = $tests - $errors;
356 print "TOTAL:          ".substr("           $tests", -12)."\t".substr("     $pass", -6)."\t".substr("     $errors", -6)."\n\n";
357 print "NO ERRORS!  ALL TESTS WERE SUCCESSFUL!\n\n" if (!$errors);
358