Check return smaller of ret and f.
[oweals/openssl.git] / fips / fipsalgtest.pl
1 #!/usr/bin/perl -w
2 # Perl utility to run or verify FIPS 140-2 CAVP algorithm tests based on the
3 # pathnames of input algorithm test files actually present (the unqualified
4 # file names are consistent but the pathnames are not).
5 #
6
7 # FIPS test definitions
8 # List of all the unqualified file names we expect and command lines to run
9
10 # DSA tests
11 my @fips_dsa_test_list = (
12
13     "DSA",
14
15     [ "PQGGen",  "fips_dssvs pqg", "path:[^C]DSA/.*PQGGen" ],
16     [ "KeyPair", "fips_dssvs keypair", "path:[^C]DSA/.*KeyPair" ],
17     [ "SigGen",  "fips_dssvs siggen", "path:[^C]DSA/.*SigGen" ],
18     [ "SigVer",  "fips_dssvs sigver", "path:[^C]DSA/.*SigVer" ]
19
20 );
21
22 my @fips_dsa_pqgver_test_list = (
23
24     [ "PQGVer",  "fips_dssvs pqgver", "path:[^C]DSA/.*PQGVer" ]
25
26 );
27
28 # DSA2 tests
29 my @fips_dsa2_test_list = (
30
31     "DSA2",
32
33     [ "PQGGen",  "fips_dssvs pqg", "path:[^C]DSA2/.*PQGGen" ],
34     [ "KeyPair", "fips_dssvs keypair", "path:[^C]DSA2/.*KeyPair" ],
35     [ "SigGen",  "fips_dssvs siggen", "path:[^C]DSA2/.*SigGen" ],
36     [ "SigVer",  "fips_dssvs sigver", "path:[^C]DSA2/.*SigVer" ],
37     [ "PQGVer",  "fips_dssvs pqgver", "path:[^C]DSA2/.*PQGVer" ]
38
39 );
40
41 # ECDSA and ECDSA2 tests
42 my @fips_ecdsa_test_list = (
43
44     "ECDSA",
45
46     [ "KeyPair", "fips_ecdsavs KeyPair", "path:/ECDSA/.*KeyPair" ],
47     [ "PKV",  "fips_ecdsavs PKV", "path:/ECDSA/.*PKV" ],
48     [ "SigGen",  "fips_ecdsavs SigGen", "path:/ECDSA/.*SigGen" ],
49     [ "SigVer",  "fips_ecdsavs SigVer", "path:/ECDSA/.*SigVer" ],
50
51     "ECDSA2",
52
53     [ "KeyPair", "fips_ecdsavs KeyPair", "path:/ECDSA2/.*KeyPair" ],
54     [ "PKV",  "fips_ecdsavs PKV", "path:/ECDSA2/.*PKV" ],
55     [ "SigGen",  "fips_ecdsavs SigGen", "path:/ECDSA2/.*SigGen" ],
56     [ "SigVer",  "fips_ecdsavs SigVer", "path:/ECDSA2/.*SigVer" ],
57
58 );
59
60 # RSA tests
61
62 my @fips_rsa_test_list = (
63
64     "RSA",
65
66     [ "SigGen15",  "fips_rsastest" ],
67     [ "SigVer15",  "fips_rsavtest" ],
68     [ "SigVerRSA", "fips_rsavtest -x931" ],
69     [ "KeyGenRSA", "fips_rsagtest" ],
70     [ "SigGenRSA", "fips_rsastest -x931" ]
71
72 );
73
74 # Special cases for PSS. The filename itself is
75 # not sufficient to determine the test. Addditionally we
76 # need to examine the file contents to determine the salt length
77 # In these cases the test filename has (saltlen) appended.
78
79 # RSA PSS salt length 0 tests
80
81 my @fips_rsa_pss0_test_list = (
82
83     [ "SigGenPSS(0)", "fips_rsastest -saltlen 0",
84                                         'file:^\s*#\s*salt\s+len:\s+0\s*$' ],
85     [ "SigVerPSS(0)", "fips_rsavtest -saltlen 0",
86                                         'file:^\s*#\s*salt\s+len:\s+0\s*$' ],
87
88 );
89
90 # RSA PSS salt length 62 tests
91
92 my @fips_rsa_pss62_test_list = (
93     [ "SigGenPSS(62)", "fips_rsastest -saltlen 62",
94                                         'file:^\s*#\s*salt\s+len:\s+62\s*$' ],
95     [ "SigVerPSS(62)", "fips_rsavtest -saltlen 62",
96                                         'file:^\s*#\s*salt\s+len:\s+62\s*$' ],
97 );
98
99 # SHA tests
100
101 my @fips_sha_test_list = (
102
103     "SHA",
104
105     [ "SHA1LongMsg",    "fips_shatest" ],
106     [ "SHA1Monte",      "fips_shatest" ],
107     [ "SHA1ShortMsg",   "fips_shatest" ],
108     [ "SHA224LongMsg",  "fips_shatest" ],
109     [ "SHA224Monte",    "fips_shatest" ],
110     [ "SHA224ShortMsg", "fips_shatest" ],
111     [ "SHA256LongMsg",  "fips_shatest" ],
112     [ "SHA256Monte",    "fips_shatest" ],
113     [ "SHA256ShortMsg", "fips_shatest" ],
114     [ "SHA384LongMsg",  "fips_shatest" ],
115     [ "SHA384Monte",    "fips_shatest" ],
116     [ "SHA384ShortMsg", "fips_shatest" ],
117     [ "SHA512LongMsg",  "fips_shatest" ],
118     [ "SHA512Monte",    "fips_shatest" ],
119     [ "SHA512ShortMsg", "fips_shatest" ]
120
121 );
122
123 # HMAC
124
125 my @fips_hmac_test_list = (
126
127     "HMAC",
128
129     [ "HMAC", "fips_hmactest" ]
130
131 );
132
133 # CMAC
134
135 my @fips_cmac_test_list = (
136
137     "CMAC",
138
139     [ "CMACGenAES128", "fips_cmactest -a aes128 -g" ],
140     [ "CMACVerAES128", "fips_cmactest -a aes128 -v" ],
141     [ "CMACGenAES192", "fips_cmactest -a aes192 -g" ],
142     [ "CMACVerAES192", "fips_cmactest -a aes192 -v" ],
143     [ "CMACGenAES256", "fips_cmactest -a aes256 -g" ],
144     [ "CMACVerAES256", "fips_cmactest -a aes256 -v" ],
145     [ "CMACGenTDES3", "fips_cmactest -a tdes3 -g" ],
146     [ "CMACVerTDES3", "fips_cmactest -a tdes3 -v" ],
147
148 );
149
150 # RAND tests, AES version
151
152 my @fips_rand_aes_test_list = (
153
154     "RAND (AES)",
155
156     [ "ANSI931_AES128MCT", "fips_rngvs mct" ],
157     [ "ANSI931_AES192MCT", "fips_rngvs mct" ],
158     [ "ANSI931_AES256MCT", "fips_rngvs mct" ],
159     [ "ANSI931_AES128VST", "fips_rngvs vst" ],
160     [ "ANSI931_AES192VST", "fips_rngvs vst" ],
161     [ "ANSI931_AES256VST", "fips_rngvs vst" ]
162
163 );
164
165 # RAND tests, DES2 version
166
167 my @fips_rand_des2_test_list = (
168
169     "RAND (DES2)",
170
171     [ "ANSI931_TDES2MCT", "fips_rngvs mct" ],
172     [ "ANSI931_TDES2VST", "fips_rngvs vst" ]
173
174 );
175
176 # AES tests
177
178 my @fips_aes_test_list = (
179
180     "AES",
181
182     [ "CBCGFSbox128",     "fips_aesavs -f" ],
183     [ "CBCGFSbox192",     "fips_aesavs -f" ],
184     [ "CBCGFSbox256",     "fips_aesavs -f" ],
185     [ "CBCKeySbox128",    "fips_aesavs -f" ],
186     [ "CBCKeySbox192",    "fips_aesavs -f" ],
187     [ "CBCKeySbox256",    "fips_aesavs -f" ],
188     [ "CBCMCT128",        "fips_aesavs -f" ],
189     [ "CBCMCT192",        "fips_aesavs -f" ],
190     [ "CBCMCT256",        "fips_aesavs -f" ],
191     [ "CBCMMT128",        "fips_aesavs -f" ],
192     [ "CBCMMT192",        "fips_aesavs -f" ],
193     [ "CBCMMT256",        "fips_aesavs -f" ],
194     [ "CBCVarKey128",     "fips_aesavs -f" ],
195     [ "CBCVarKey192",     "fips_aesavs -f" ],
196     [ "CBCVarKey256",     "fips_aesavs -f" ],
197     [ "CBCVarTxt128",     "fips_aesavs -f" ],
198     [ "CBCVarTxt192",     "fips_aesavs -f" ],
199     [ "CBCVarTxt256",     "fips_aesavs -f" ],
200     [ "CFB128GFSbox128",  "fips_aesavs -f" ],
201     [ "CFB128GFSbox192",  "fips_aesavs -f" ],
202     [ "CFB128GFSbox256",  "fips_aesavs -f" ],
203     [ "CFB128KeySbox128", "fips_aesavs -f" ],
204     [ "CFB128KeySbox192", "fips_aesavs -f" ],
205     [ "CFB128KeySbox256", "fips_aesavs -f" ],
206     [ "CFB128MCT128",     "fips_aesavs -f" ],
207     [ "CFB128MCT192",     "fips_aesavs -f" ],
208     [ "CFB128MCT256",     "fips_aesavs -f" ],
209     [ "CFB128MMT128",     "fips_aesavs -f" ],
210     [ "CFB128MMT192",     "fips_aesavs -f" ],
211     [ "CFB128MMT256",     "fips_aesavs -f" ],
212     [ "CFB128VarKey128",  "fips_aesavs -f" ],
213     [ "CFB128VarKey192",  "fips_aesavs -f" ],
214     [ "CFB128VarKey256",  "fips_aesavs -f" ],
215     [ "CFB128VarTxt128",  "fips_aesavs -f" ],
216     [ "CFB128VarTxt192",  "fips_aesavs -f" ],
217     [ "CFB128VarTxt256",  "fips_aesavs -f" ],
218     [ "CFB8GFSbox128",    "fips_aesavs -f" ],
219     [ "CFB8GFSbox192",    "fips_aesavs -f" ],
220     [ "CFB8GFSbox256",    "fips_aesavs -f" ],
221     [ "CFB8KeySbox128",   "fips_aesavs -f" ],
222     [ "CFB8KeySbox192",   "fips_aesavs -f" ],
223     [ "CFB8KeySbox256",   "fips_aesavs -f" ],
224     [ "CFB8MCT128",       "fips_aesavs -f" ],
225     [ "CFB8MCT192",       "fips_aesavs -f" ],
226     [ "CFB8MCT256",       "fips_aesavs -f" ],
227     [ "CFB8MMT128",       "fips_aesavs -f" ],
228     [ "CFB8MMT192",       "fips_aesavs -f" ],
229     [ "CFB8MMT256",       "fips_aesavs -f" ],
230     [ "CFB8VarKey128",    "fips_aesavs -f" ],
231     [ "CFB8VarKey192",    "fips_aesavs -f" ],
232     [ "CFB8VarKey256",    "fips_aesavs -f" ],
233     [ "CFB8VarTxt128",    "fips_aesavs -f" ],
234     [ "CFB8VarTxt192",    "fips_aesavs -f" ],
235     [ "CFB8VarTxt256",    "fips_aesavs -f" ],
236
237     [ "ECBGFSbox128",  "fips_aesavs -f" ],
238     [ "ECBGFSbox192",  "fips_aesavs -f" ],
239     [ "ECBGFSbox256",  "fips_aesavs -f" ],
240     [ "ECBKeySbox128", "fips_aesavs -f" ],
241     [ "ECBKeySbox192", "fips_aesavs -f" ],
242     [ "ECBKeySbox256", "fips_aesavs -f" ],
243     [ "ECBMCT128",     "fips_aesavs -f" ],
244     [ "ECBMCT192",     "fips_aesavs -f" ],
245     [ "ECBMCT256",     "fips_aesavs -f" ],
246     [ "ECBMMT128",     "fips_aesavs -f" ],
247     [ "ECBMMT192",     "fips_aesavs -f" ],
248     [ "ECBMMT256",     "fips_aesavs -f" ],
249     [ "ECBVarKey128",  "fips_aesavs -f" ],
250     [ "ECBVarKey192",  "fips_aesavs -f" ],
251     [ "ECBVarKey256",  "fips_aesavs -f" ],
252     [ "ECBVarTxt128",  "fips_aesavs -f" ],
253     [ "ECBVarTxt192",  "fips_aesavs -f" ],
254     [ "ECBVarTxt256",  "fips_aesavs -f" ],
255     [ "OFBGFSbox128",  "fips_aesavs -f" ],
256     [ "OFBGFSbox192",  "fips_aesavs -f" ],
257     [ "OFBGFSbox256",  "fips_aesavs -f" ],
258     [ "OFBKeySbox128", "fips_aesavs -f" ],
259     [ "OFBKeySbox192", "fips_aesavs -f" ],
260     [ "OFBKeySbox256", "fips_aesavs -f" ],
261     [ "OFBMCT128",     "fips_aesavs -f" ],
262     [ "OFBMCT192",     "fips_aesavs -f" ],
263     [ "OFBMCT256",     "fips_aesavs -f" ],
264     [ "OFBMMT128",     "fips_aesavs -f" ],
265     [ "OFBMMT192",     "fips_aesavs -f" ],
266     [ "OFBMMT256",     "fips_aesavs -f" ],
267     [ "OFBVarKey128",  "fips_aesavs -f" ],
268     [ "OFBVarKey192",  "fips_aesavs -f" ],
269     [ "OFBVarKey256",  "fips_aesavs -f" ],
270     [ "OFBVarTxt128",  "fips_aesavs -f" ],
271     [ "OFBVarTxt192",  "fips_aesavs -f" ],
272     [ "OFBVarTxt256",  "fips_aesavs -f" ]
273
274 );
275
276 my @fips_aes_cfb1_test_list = (
277
278     # AES CFB1 tests
279
280     [ "CFB1GFSbox128",  "fips_aesavs -f" ],
281     [ "CFB1GFSbox192",  "fips_aesavs -f" ],
282     [ "CFB1GFSbox256",  "fips_aesavs -f" ],
283     [ "CFB1KeySbox128", "fips_aesavs -f" ],
284     [ "CFB1KeySbox192", "fips_aesavs -f" ],
285     [ "CFB1KeySbox256", "fips_aesavs -f" ],
286     [ "CFB1MCT128",     "fips_aesavs -f" ],
287     [ "CFB1MCT192",     "fips_aesavs -f" ],
288     [ "CFB1MCT256",     "fips_aesavs -f" ],
289     [ "CFB1MMT128",     "fips_aesavs -f" ],
290     [ "CFB1MMT192",     "fips_aesavs -f" ],
291     [ "CFB1MMT256",     "fips_aesavs -f" ],
292     [ "CFB1VarKey128",  "fips_aesavs -f" ],
293     [ "CFB1VarKey192",  "fips_aesavs -f" ],
294     [ "CFB1VarKey256",  "fips_aesavs -f" ],
295     [ "CFB1VarTxt128",  "fips_aesavs -f" ],
296     [ "CFB1VarTxt192",  "fips_aesavs -f" ],
297     [ "CFB1VarTxt256",  "fips_aesavs -f" ]
298
299 );
300
301 my @fips_aes_ccm_test_list = (
302
303     # AES CCM tests
304
305     "AES CCM",
306
307     [ "DVPT128",  "fips_gcmtest -ccm" ],
308     [ "DVPT192",  "fips_gcmtest -ccm" ],
309     [ "DVPT256",  "fips_gcmtest -ccm" ],
310     [ "VADT128",  "fips_gcmtest -ccm" ],
311     [ "VADT192",  "fips_gcmtest -ccm" ],
312     [ "VADT256",  "fips_gcmtest -ccm" ],
313     [ "VNT128",  "fips_gcmtest -ccm" ],
314     [ "VNT192",  "fips_gcmtest -ccm" ],
315     [ "VNT256",  "fips_gcmtest -ccm" ],
316     [ "VPT128",  "fips_gcmtest -ccm" ],
317     [ "VPT192",  "fips_gcmtest -ccm" ],
318     [ "VPT256",  "fips_gcmtest -ccm" ],
319     [ "VTT128",  "fips_gcmtest -ccm" ],
320     [ "VTT192",  "fips_gcmtest -ccm" ],
321     [ "VTT256",  "fips_gcmtest -ccm" ]
322
323 );
324
325 my @fips_aes_gcm_test_list = (
326
327     # AES GCM tests
328
329     "AES GCM",
330
331     [ "gcmDecrypt128",  "fips_gcmtest -decrypt" ],
332     [ "gcmDecrypt192",  "fips_gcmtest -decrypt" ],
333     [ "gcmDecrypt256",  "fips_gcmtest -decrypt" ],
334     [ "gcmEncryptIntIV128",  "fips_gcmtest -encrypt" ],
335     [ "gcmEncryptIntIV192",  "fips_gcmtest -encrypt" ],
336     [ "gcmEncryptIntIV256",  "fips_gcmtest -encrypt" ],
337
338 );
339
340 my @fips_aes_xts_test_list = (
341     # AES XTS tests
342
343     "AES XTS",
344
345     [ "XTSGenAES128",  "fips_gcmtest -xts" ],
346     [ "XTSGenAES256",  "fips_gcmtest -xts" ],
347
348 );
349
350 # Triple DES tests
351
352 my @fips_des3_test_list = (
353
354     "Triple DES",
355
356     [ "TCBCinvperm",   "fips_desmovs -f" ],
357     [ "TCBCMMT1",      "fips_desmovs -f" ],
358     [ "TCBCMMT2",      "fips_desmovs -f" ],
359     [ "TCBCMMT3",      "fips_desmovs -f" ],
360     [ "TCBCMonte1",    "fips_desmovs -f" ],
361     [ "TCBCMonte2",    "fips_desmovs -f" ],
362     [ "TCBCMonte3",    "fips_desmovs -f" ],
363     [ "TCBCpermop",    "fips_desmovs -f" ],
364     [ "TCBCsubtab",    "fips_desmovs -f" ],
365     [ "TCBCvarkey",    "fips_desmovs -f" ],
366     [ "TCBCvartext",   "fips_desmovs -f" ],
367     [ "TCFB64invperm", "fips_desmovs -f" ],
368     [ "TCFB64MMT1",    "fips_desmovs -f" ],
369     [ "TCFB64MMT2",    "fips_desmovs -f" ],
370     [ "TCFB64MMT3",    "fips_desmovs -f" ],
371     [ "TCFB64Monte1",  "fips_desmovs -f" ],
372     [ "TCFB64Monte2",  "fips_desmovs -f" ],
373     [ "TCFB64Monte3",  "fips_desmovs -f" ],
374     [ "TCFB64permop",  "fips_desmovs -f" ],
375     [ "TCFB64subtab",  "fips_desmovs -f" ],
376     [ "TCFB64varkey",  "fips_desmovs -f" ],
377     [ "TCFB64vartext", "fips_desmovs -f" ],
378     [ "TCFB8invperm",  "fips_desmovs -f" ],
379     [ "TCFB8MMT1",     "fips_desmovs -f" ],
380     [ "TCFB8MMT2",     "fips_desmovs -f" ],
381     [ "TCFB8MMT3",     "fips_desmovs -f" ],
382     [ "TCFB8Monte1",   "fips_desmovs -f" ],
383     [ "TCFB8Monte2",   "fips_desmovs -f" ],
384     [ "TCFB8Monte3",   "fips_desmovs -f" ],
385     [ "TCFB8permop",   "fips_desmovs -f" ],
386     [ "TCFB8subtab",   "fips_desmovs -f" ],
387     [ "TCFB8varkey",   "fips_desmovs -f" ],
388     [ "TCFB8vartext",  "fips_desmovs -f" ],
389     [ "TECBinvperm",   "fips_desmovs -f" ],
390     [ "TECBMMT1",      "fips_desmovs -f" ],
391     [ "TECBMMT2",      "fips_desmovs -f" ],
392     [ "TECBMMT3",      "fips_desmovs -f" ],
393     [ "TECBMonte1",    "fips_desmovs -f" ],
394     [ "TECBMonte2",    "fips_desmovs -f" ],
395     [ "TECBMonte3",    "fips_desmovs -f" ],
396     [ "TECBpermop",    "fips_desmovs -f" ],
397     [ "TECBsubtab",    "fips_desmovs -f" ],
398     [ "TECBvarkey",    "fips_desmovs -f" ],
399     [ "TECBvartext",   "fips_desmovs -f" ],
400     [ "TOFBinvperm",   "fips_desmovs -f" ],
401     [ "TOFBMMT1",      "fips_desmovs -f" ],
402     [ "TOFBMMT2",      "fips_desmovs -f" ],
403     [ "TOFBMMT3",      "fips_desmovs -f" ],
404     [ "TOFBMonte1",    "fips_desmovs -f" ],
405     [ "TOFBMonte2",    "fips_desmovs -f" ],
406     [ "TOFBMonte3",    "fips_desmovs -f" ],
407     [ "TOFBpermop",    "fips_desmovs -f" ],
408     [ "TOFBsubtab",    "fips_desmovs -f" ],
409     [ "TOFBvarkey",    "fips_desmovs -f" ],
410     [ "TOFBvartext",   "fips_desmovs -f" ]
411
412 );
413
414 my @fips_des3_cfb1_test_list = (
415
416     # DES3 CFB1 tests
417
418     [ "TCFB1invperm",  "fips_desmovs -f" ],
419     [ "TCFB1MMT1",     "fips_desmovs -f" ],
420     [ "TCFB1MMT2",     "fips_desmovs -f" ],
421     [ "TCFB1MMT3",     "fips_desmovs -f" ],
422     [ "TCFB1Monte1",   "fips_desmovs -f" ],
423     [ "TCFB1Monte2",   "fips_desmovs -f" ],
424     [ "TCFB1Monte3",   "fips_desmovs -f" ],
425     [ "TCFB1permop",   "fips_desmovs -f" ],
426     [ "TCFB1subtab",   "fips_desmovs -f" ],
427     [ "TCFB1varkey",   "fips_desmovs -f" ],
428     [ "TCFB1vartext",  "fips_desmovs -f" ],
429
430 );
431
432 my @fips_drbg_test_list = (
433
434     # SP800-90 DRBG tests
435     "SP800-90 DRBG",
436     [ "CTR_DRBG",   "fips_drbgvs" ],
437     [ "Dual_EC_DRBG",   "fips_drbgvs" ],
438     [ "Hash_DRBG",  "fips_drbgvs" ],
439     [ "HMAC_DRBG",  "fips_drbgvs" ]
440
441 );
442
443 my @fips_dh_test_list = (
444
445     # DH
446     "DH Ephemeral Primitives Only",
447     [ "KASValidityTest_FFCEphem_NOKC_ZZOnly_init",   "fips_dhvs dhver" ],
448     [ "KASValidityTest_FFCEphem_NOKC_ZZOnly_resp",   "fips_dhvs dhver" ],
449
450 );
451
452 my @fips_ecdh_test_list = (
453
454     # ECDH
455     "ECDH Ephemeral Primitives Only",
456     [ "KAS_ECC_CDH_PrimitiveTest", "fips_ecdhvs ecdhgen" ],
457 #    [ "KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_init",
458 #                                                       "fips_ecdhvs ecdhver" ],
459 #    [ "KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_resp",
460 #                                                       "fips_ecdhvs ecdhver" ],
461
462 );
463
464
465 # Verification special cases.
466 # In most cases the output of a test is deterministic and
467 # it can be compared to a known good result. A few involve
468 # the genration and use of random keys and the output will
469 # be different each time. In thoses cases we perform special tests
470 # to simply check their consistency. For example signature generation
471 # output will be run through signature verification to see if all outputs
472 # show as valid.
473 #
474
475 my %verify_special = (
476     "DSA:PQGGen"        => "fips_dssvs pqgver",
477     "DSA:KeyPair"       => "fips_dssvs keyver",
478     "DSA:SigGen"        => "fips_dssvs sigver",
479     "DSA2:PQGGen"        => "fips_dssvs pqgver",
480     "DSA2:KeyPair"       => "fips_dssvs keyver",
481     "DSA2:SigGen"        => "fips_dssvs sigver",
482     "ECDSA:KeyPair"     => "fips_ecdsavs PKV",
483     "ECDSA:SigGen"      => "fips_ecdsavs SigVer",
484     "ECDSA2:KeyPair"    => "fips_ecdsavs PKV",
485     "ECDSA2:SigGen"     => "fips_ecdsavs SigVer",
486     "RSA:SigGen15"      => "fips_rsavtest",
487     "RSA:SigGenRSA"     => "fips_rsavtest -x931",
488     "RSA:SigGenPSS(0)"  => "fips_rsavtest -saltlen 0",
489     "RSA:SigGenPSS(62)" => "fips_rsavtest -saltlen 62",
490     "ECDH Ephemeral Primitives Only:KAS_ECC_CDH_PrimitiveTest" => "skip"
491 );
492
493 my $win32  = $^O =~ m/mswin/i;
494 my $onedir = 0;
495 my $filter = "";
496 my $tvdir;
497 my $tprefix;
498 my $sfprefix = "";
499 my $debug          = 0;
500 my $quiet          = 0;
501 my $notest         = 0;
502 my $verify         = 1;
503 my $rspdir         = "resp";
504 my $ignore_missing = 0;
505 my $ignore_bogus   = 0;
506 my $bufout         = '';
507 my $list_tests     = 0;
508 my $minimal_script = 0;
509 my $outfile        = '';
510 my $no_warn_missing = 0;
511 my $no_warn_bogus = 0;
512 my $rmcmd = "rm -rf";
513 my $mkcmd = "mkdir";
514 my $cmpall = 0;
515
516 my %fips_enabled = (
517     "dsa"        => 1,
518     "dsa2"       => 2,
519     "dsa-pqgver"  => 2,
520     "ecdsa"      => 2,
521     "rsa"        => 1,
522     "rsa-pss0"  => 2,
523     "rsa-pss62" => 1,
524     "sha"        => 1,
525     "hmac"       => 1,
526     "cmac"       => 2,
527     "rand-aes"  => 1,
528     "rand-des2" => 0,
529     "aes"        => 1,
530     "aes-cfb1"  => 2,
531     "des3"       => 1,
532     "des3-cfb1" => 2,
533     "drbg"      => 2,
534     "aes-ccm"   => 2,
535     "aes-xts"   => 2,
536     "aes-gcm"   => 2,
537     "dh"        => 0,
538     "ecdh"      => 2,
539     "v2"        => 1,
540 );
541
542 foreach (@ARGV) {
543     if ( $_ eq "--win32" ) {
544         $win32 = 1;
545     }
546     elsif ( $_ eq "--onedir" ) {
547         $onedir = 1;
548     }
549     elsif ( $_ eq "--debug" ) {
550         $debug = 1;
551     }
552     elsif ( $_ eq "--quiet-missing" ) {
553         $ignore_missing = 1;
554         $no_warn_missing = 1;
555     }
556     elsif ( $_ eq "--ignore-missing" ) {
557         $ignore_missing = 1;
558     }
559     elsif ( $_ eq "--quiet-bogus" ) {
560         $ignore_bogus = 1;
561         $no_warn_bogus = 1;
562     }
563     elsif ( $_ eq "--ignore-bogus" ) {
564         $ignore_bogus = 1;
565     }
566     elsif ( $_ eq "--minimal-script" ) {
567         $minimal_script = 1;
568     }
569     elsif (/--generate-script=(.*)$/) {
570         $outfile = $1;
571         $verify = 0;
572     } elsif ( $_ eq "--generate" ) {
573         $verify = 0;
574     }
575     elsif ( $_ eq "--compare-all" ) {
576         $cmpall = 1;
577     }
578     elsif ( $_ eq "--notest" ) {
579         $notest = 1;
580     }
581     elsif ( $_ eq "--quiet" ) {
582         $quiet = 1;
583     }
584     elsif (/--dir=(.*)$/) {
585         $tvdir = $1;
586     }
587     elsif (/--rspdir=(.*)$/) {
588         $rspdir = $1;
589     }
590     elsif (/--tprefix=(.*)$/) {
591         $tprefix = $1;
592     }
593     elsif (/^--disable-all$/) {
594         foreach (keys %fips_enabled) {
595                 $fips_enabled{$_} = 0;
596         }
597     }
598     elsif (/^--(enable|disable)-(.*)$/) {
599         if ( !exists $fips_enabled{$2} ) {
600             print STDERR "Unknown test $2\n";
601             exit(1);
602         }
603         if ( $1 eq "enable" ) {
604             $fips_enabled{$2} = 1;
605         }
606         else {
607             $fips_enabled{$2} = 0;
608         }
609     }
610     elsif (/--filter=(.*)$/) {
611         $filter = $1;
612     }
613     elsif (/--rm=(.*)$/) {
614         $rmcmd = $1;
615     }
616     elsif (/--script-tprefix=(.*)$/) {
617         $stprefix = $1;
618     }
619     elsif (/--script-fprefix=(.*)$/) {
620         $sfprefix = $1;
621     }
622     elsif (/--mkdir=(.*)$/) {
623         $mkcmd = $1;
624     }
625     elsif (/^--list-tests$/) {
626         $list_tests = 1;
627     }
628     else {
629         Help();
630         exit(1);
631     }
632 }
633
634 my @fips_test_list;
635
636
637 if (!$fips_enabled{"v2"}) {
638         foreach (keys %fips_enabled) {
639                 $fips_enabled{$_} = 0 if $fips_enabled{$_} == 2;
640         }
641 }
642
643 push @fips_test_list, @fips_dsa_test_list       if $fips_enabled{"dsa"};
644 push @fips_test_list, @fips_dsa_pqgver_test_list if $fips_enabled{"dsa-pqgver"};
645 push @fips_test_list, @fips_dsa2_test_list      if $fips_enabled{"dsa2"};
646 push @fips_test_list, @fips_ecdsa_test_list     if $fips_enabled{"ecdsa"};
647 push @fips_test_list, @fips_rsa_test_list       if $fips_enabled{"rsa"};
648 push @fips_test_list, @fips_rsa_pss0_test_list  if $fips_enabled{"rsa-pss0"};
649 push @fips_test_list, @fips_rsa_pss62_test_list if $fips_enabled{"rsa-pss62"};
650 push @fips_test_list, @fips_sha_test_list       if $fips_enabled{"sha"};
651 push @fips_test_list, @fips_hmac_test_list      if $fips_enabled{"hmac"};
652 push @fips_test_list, @fips_cmac_test_list      if $fips_enabled{"cmac"};
653 push @fips_test_list, @fips_rand_aes_test_list  if $fips_enabled{"rand-aes"};
654 push @fips_test_list, @fips_rand_des2_test_list if $fips_enabled{"rand-des2"};
655 push @fips_test_list, @fips_aes_test_list       if $fips_enabled{"aes"};
656 push @fips_test_list, @fips_aes_cfb1_test_list  if $fips_enabled{"aes-cfb1"};
657 push @fips_test_list, @fips_des3_test_list      if $fips_enabled{"des3"};
658 push @fips_test_list, @fips_des3_cfb1_test_list if $fips_enabled{"des3-cfb1"};
659 push @fips_test_list, @fips_drbg_test_list      if $fips_enabled{"drbg"};
660 push @fips_test_list, @fips_aes_ccm_test_list   if $fips_enabled{"aes-ccm"};
661 push @fips_test_list, @fips_aes_gcm_test_list   if $fips_enabled{"aes-gcm"};
662 push @fips_test_list, @fips_aes_xts_test_list   if $fips_enabled{"aes-xts"};
663 push @fips_test_list, @fips_dh_test_list        if $fips_enabled{"dh"};
664 push @fips_test_list, @fips_ecdh_test_list      if $fips_enabled{"ecdh"};
665
666 if ($list_tests) {
667     my ( $test, $en );
668     print "=====TEST LIST=====\n";
669     foreach $test ( sort keys %fips_enabled ) {
670         $en = $fips_enabled{$test};
671         $test =~ tr/[a-z]/[A-Z]/;
672         printf "%-10s %s\n", $test, $en ? "enabled" : "disabled";
673     }
674     exit(0);
675 }
676
677 foreach (@fips_test_list) {
678     next unless ref($_);
679     my $nm = $$_[0];
680     $$_[3] = "";
681     $$_[4] = "";
682 }
683
684 $tvdir = "." unless defined $tvdir;
685
686 if ($win32) {
687     if ( !defined $tprefix ) {
688         if ($onedir) {
689             $tprefix = ".\\";
690         }
691         else {
692             $tprefix = "..\\out32dll\\";
693         }
694     }
695 }
696 else {
697     if ($onedir) {
698         $tprefix       = "./" unless defined $tprefix;
699     }
700     else {
701         $tprefix       = "../test/" unless defined $tprefix;
702     }
703 }
704
705 sanity_check_exe( $win32, $tprefix) if $outfile eq "";
706
707 find_files( $filter, $tvdir );
708
709 sanity_check_files();
710
711 my ( $runerr, $cmperr, $cmpok, $scheckrunerr, $scheckerr, $scheckok, $skipcnt )
712   = ( 0, 0, 0, 0, 0, 0, 0 );
713
714 exit(0) if $notest;
715 print "Outputting commands to $outfile\n" if $outfile ne "";
716 run_tests( $verify, $win32, $tprefix, $filter, $tvdir, $outfile );
717
718 if ($verify) {
719     print "ALGORITHM TEST VERIFY SUMMARY REPORT:\n";
720     print "Tests skipped due to missing files:        $skipcnt\n";
721     print "Algorithm test program execution failures: $runerr\n";
722     print "Test comparisons successful:               $cmpok\n";
723     print "Test comparisons failed:                   $cmperr\n";
724     print "Test sanity checks successful:             $scheckok\n";
725     print "Test sanity checks failed:                 $scheckerr\n";
726     print "Sanity check program execution failures:   $scheckrunerr\n";
727
728     if ( $runerr || $cmperr || $scheckrunerr || $scheckerr ) {
729         print "***TEST FAILURE***\n";
730     }
731     else {
732         print "***ALL TESTS SUCCESSFUL***\n";
733     }
734 }
735 elsif ($outfile eq "") {
736     print "ALGORITHM TEST SUMMARY REPORT:\n";
737     print "Tests skipped due to missing files:        $skipcnt\n";
738     print "Algorithm test program execution failures: $runerr\n";
739
740     if ($runerr) {
741         print "***TEST FAILURE***\n";
742     }
743     else {
744         print "***ALL TESTS SUCCESSFUL***\n";
745     }
746 }
747
748 #--------------------------------
749 sub Help {
750     ( my $cmd ) = ( $0 =~ m#([^/]+)$# );
751     print <<EOF;
752 $cmd: generate run CAVP algorithm tests
753         --debug                       Enable debug output
754         --dir=<dirname>               Optional root for *.req file search
755         --filter=<regexp>             Regex for input files of interest
756         --onedir <dirname>            Assume all components in current directory
757         --rspdir=<dirname>            Name of subdirectories containing *.rsp files, default "resp"
758         --tprefix=<prefix>            Pathname prefix for directory containing test programs
759         --ignore-bogus                Ignore duplicate or bogus files
760         --ignore-missing              Ignore missing test files
761         --quiet                       Shhh....
762         --quiet-bogus                 Skip unrecognized file warnings
763         --quiet-missing               Skip missing request file warnings
764         --generate                    Generate algorithm test output
765         --generate-script=<filename>  Generate script to call algorithm programs
766         --minimal-script              Simplest possible output for --generate-script
767         --win32                       Win32 environment
768         --compare-all                 Verify unconditionally for all tests
769         --list-tests                  Show individual tests
770         --mkdir=<cmd>                 Specify "mkdir" command
771         --notest                      Exit before running tests
772         --rm=<cmd>                    Specify "rm" command
773         --script-tprefix              Pathname prefix for --generate-script output
774         --enable-<alg>                Enable algorithm set <alg>.
775         --disable-<alg>               Disable algorithm set <alg>.
776         Where <alg> can be one of:
777 EOF
778
779 while (my ($key, $value) = each %fips_enabled)
780         {
781         printf "\t\t%-20s(%s by default)\n", $key ,
782                         $value == 1 ? "enabled" : "disabled";
783         }
784 }
785
786 # Sanity check to see if all necessary executables exist
787
788 sub sanity_check_exe {
789     my ( $win32, $tprefix, ) = @_;
790     my %exe_list;
791     my $bad = 0;
792     foreach (@fips_test_list) {
793         next unless ref($_);
794         my $cmd = $_->[1];
795         $cmd =~ s/ .*$//;
796         $cmd = $tprefix . $cmd;
797         $cmd .= ".exe" if $win32;
798         $exe_list{$cmd} = 1;
799     }
800
801     foreach ( sort keys %exe_list ) {
802         if ( !-f $_ ) {
803             print STDERR "ERROR: can't find executable $_\n";
804             $bad = 1;
805         }
806     }
807     if ($bad) {
808         print STDERR "FATAL ERROR: executables missing\n";
809         exit(1);
810     }
811     elsif ($debug) {
812         print STDERR "Executable sanity check passed OK\n";
813     }
814 }
815
816 # Search for all request and response files
817
818 sub find_files {
819     my ( $filter, $dir ) = @_;
820     my ( $dirh, $testname, $tref );
821     opendir( $dirh, $dir );
822     while ( $_ = readdir($dirh) ) {
823         next if ( $_ eq "." || $_ eq ".." );
824         $_ = "$dir/$_";
825         if ( -f "$_" ) {
826             if (/\/([^\/]*)\.rsp$/) {
827                 $tref = find_test($1, $_);
828                 if ( defined $tref ) {
829                     $testname = $$tref[0];
830                     if ( $$tref[4] eq "" ) {
831                         $$tref[4] = $_;
832                     }
833                     else {
834                         print STDERR
835 "WARNING: duplicate response file $_ for test $testname\n";
836                         $nbogus++;
837                     }
838                 }
839                 else {
840                     print STDERR "WARNING: bogus file $_\n" unless $no_warn_bogus;
841                     $nbogus++;
842                 }
843             }
844             next unless /$filter.*\.req$/i;
845             if (/\/([^\/]*)\.req$/) {
846                 $tref = find_test($1, $_);
847                 if ( defined $tref ) {
848                     $testname = $$tref[0];
849                     if ( $$tref[3] eq "" ) {
850                         $$tref[3] = $_;
851                     }
852                     else {
853                         print STDERR
854 "WARNING: duplicate request file $_ for test $testname\n";
855                         $nbogus++;
856                     }
857
858                 }
859                 elsif ( !/SHAmix\.req$/ ) {
860                     print STDERR "WARNING: unrecognized filename $_\n" unless $no_warn_bogus;
861                     $nbogus++;
862                 }
863             }
864         }
865         elsif ( -d "$_" ) {
866             find_files( $filter, $_ );
867         }
868     }
869     closedir($dirh);
870 }
871 #
872 # Find test based on filename.
873 # In ambiguous cases search file contents for a match
874 #
875
876 sub find_test {
877     my ( $test, $path ) = @_;
878     foreach $tref (@fips_test_list) {
879         next unless ref($tref);
880         my ( $tst, $cmd, $excmd, $req, $resp ) = @$tref;
881         my $regexp;
882         $tst =~ s/\(.*$//;
883         $test =~ s/_186-2//;
884         if (defined $excmd) {
885                 if ($excmd =~ /^path:(.*)$/) {
886                         my $fmatch = $1;
887                         return $tref if ($path =~ /$fmatch/);
888                         next;
889                 }
890                 elsif ($excmd =~ /^file:(.*)$/) {
891                         $regexp = $1;
892                 }
893         }
894         if ($test eq $tst) {
895                 return $tref if (!defined $regexp);
896                 my $found = 0;
897                 my $line;
898                 open( IN, $path ) || die "Can't Open File $path";
899                 while ($line = <IN>) {
900                     if ($line =~ /$regexp/i) {
901                         $found = 1;
902                         last;
903                     }
904                 }
905                 close IN;
906                 return $tref if $found == 1;
907         }
908     }
909     return undef;
910 }
911
912 sub sanity_check_files {
913     my $bad = 0;
914     foreach (@fips_test_list) {
915         next unless ref($_);
916         my ( $tst, $cmd, $regexp, $req, $resp ) = @$_;
917
918         #print STDERR "FILES $tst, $cmd, $req, $resp\n";
919         if ( $req eq "" ) {
920             print STDERR "WARNING: missing request file for $tst\n" unless $no_warn_missing;
921             $bad = 1;
922             next;
923         }
924         if ( $verify && $resp eq "" ) {
925             print STDERR "WARNING: no response file for test $tst\n";
926             $bad = 1;
927         }
928         elsif ( !$verify && $resp ne "" ) {
929             print STDERR "WARNING: response file $resp will be overwritten\n";
930         }
931     }
932     if ($bad) {
933         print STDERR "ERROR: test vector file set not complete\n";
934         exit(1) unless $ignore_missing;
935     }
936     if ($nbogus) {
937         print STDERR
938           "ERROR: $nbogus bogus or duplicate request and response files\n";
939         exit(1) unless $ignore_bogus;
940     }
941     if ( $debug && !$nbogus && !$bad ) {
942         print STDERR "test vector file set complete\n";
943     }
944 }
945
946 sub run_tests {
947     my ( $verify, $win32, $tprefix, $filter, $tvdir, $outfile ) = @_;
948     my ( $tname, $tref );
949     my $bad = 0;
950     my $lastdir = "";
951     $stprefix = $tprefix unless defined $stprefix;
952     if ($outfile ne "") {
953         open OUT, ">$outfile" || die "Can't open $outfile";
954     }
955     if ($outfile ne "" && !$minimal_script) {
956         if ($win32) {
957             print OUT <<\END;
958 @echo off
959 rem Test vector run script
960 rem Auto generated by fipsalgtest.pl script
961 rem Do not edit
962
963 echo Running Algorithm Tests
964
965 END
966         } else {
967             print OUT <<END;
968 #!/bin/sh
969
970 # Test vector run script
971 # Auto generated by fipsalgtest.pl script
972 # Do not edit
973
974 echo Running Algorithm Tests
975
976 RM="$rmcmd";
977 MKDIR="$mkcmd";
978 TPREFIX=$stprefix
979
980 END
981         }
982
983     }
984
985     my $ttype = "";
986
987     foreach (@fips_test_list) {
988         if ( !ref($_) ) {
989             if ($outfile ne "") {
990                 print "Generating script for $_ tests\n";
991                 print OUT "\n\n\necho \"Running $_ tests\"\n" unless $minimal_script;
992             } else {    
993                 print "Running $_ tests\n" unless $quiet;
994             }
995             $ttype = $_;
996             next;
997         }
998         my ( $tname, $tcmd, $regexp, $req, $rsp ) = @$_;
999         my $out = $rsp;
1000         if ($verify) {
1001             $out =~ s/\.rsp$/.tst/;
1002         }
1003         if ( $req eq "" ) {
1004             print STDERR
1005               "WARNING: Request file for $tname missing: test skipped\n" unless $no_warn_missing;
1006             $skipcnt++;
1007             next;
1008         }
1009         if ( $verify && $rsp eq "" ) {
1010             print STDERR
1011               "WARNING: Response file for $tname missing: test skipped\n";
1012             $skipcnt++;
1013             next;
1014         }
1015         elsif ( !$verify ) {
1016             if ( $rsp ne "" ) {
1017                 print STDERR "WARNING: Response file for $tname deleted\n";
1018                 unlink $rsp;
1019             }
1020             $out = $req;
1021             $out =~ s|/req/(\S+)\.req|/$rspdir/$1.rsp|;
1022             my $outdir = $out;
1023             $outdir =~ s|/[^/]*$||;
1024             if ( !-d $outdir  && ($outfile eq "" || $minimal_script)) {
1025                 print STDERR "DEBUG: Creating directory $outdir\n" if $debug;
1026                 mkdir($outdir) || die "Can't create directory $outdir";
1027             }
1028             if ($outfile ne "") {
1029                 if ($win32) {
1030                     $outdir =~ tr|/|\\|;
1031                     $req =~ tr|/|\\|;
1032                     $out =~ tr|/|\\|;
1033                 }
1034                 if ($outdir ne $lastdir && !$minimal_script) {
1035                     if ($win32) {
1036                     print OUT <<END
1037 if exist \"$outdir\" rd /s /q "$outdir"
1038 md \"$outdir\"
1039
1040 END
1041                     } else {
1042                     print OUT <<END
1043 \$RM \"$outdir\"
1044 \$MKDIR \"$outdir\"
1045
1046 END
1047                     }
1048                 $lastdir = $outdir;
1049                 }
1050             }
1051         }
1052         my $cmd = "$tcmd \"$sfprefix$req\" \"$sfprefix$out\"";
1053         print STDERR "DEBUG: running test $tname\n" if ( $debug && !$verify );
1054         if ($outfile ne "") {
1055             if ($minimal_script) {
1056                 print OUT "$stprefix$cmd\n";
1057             } else {
1058                 print OUT "echo \"    running $tname test\"\n" unless $minimal_script;
1059                 print OUT "\${TPREFIX}$cmd\n";
1060             }
1061         } else {
1062             $cmd = "$tprefix$cmd";
1063             system($cmd);
1064             if ( $? != 0 ) {
1065                 print STDERR
1066                      "WARNING: error executing test $tname for command: $cmd\n";
1067                 $runerr++;
1068                 next;
1069             }
1070         }
1071         if ($verify) {
1072             if ( exists $verify_special{"$ttype:$tname"} && !$cmpall) {
1073                 my $vout = $rsp;
1074                 $vout =~ s/\.rsp$/.ver/;
1075                 $tcmd = $verify_special{"$ttype:$tname"};
1076                 if ($tcmd eq "skip") {
1077                         print STDERR "DEBUG: No verify possible: skipped.\n" if $debug;
1078                         $scheckok++;
1079                         next;
1080                 }
1081                 $cmd  = "$tprefix$tcmd ";
1082                 $cmd .= "\"$out\" \"$vout\"";
1083                 system($cmd);
1084                 if ( $? != 0 ) {
1085                     print STDERR
1086                       "WARNING: error executing verify test $tname $cmd\n";
1087                     $scheckrunerr++;
1088                     next;
1089                 }
1090                 my ( $fcount, $pcount ) = ( 0, 0 );
1091                 open VER, "$vout";
1092                 while (<VER>) {
1093                     if (/^Result\s*=\s*(\S*)\s*$/i)
1094
1095                     {
1096                         if ( $1 eq "F" ) {
1097                             $fcount++;
1098                         }
1099                         else {
1100                             $pcount++;
1101                         }
1102                     }
1103                 }
1104                 close VER;
1105
1106                 unlink $vout;
1107                 if ( $fcount || $debug ) {
1108                     print STDERR "DEBUG: $tname, Pass=$pcount, Fail=$fcount\n";
1109                 }
1110                 if ( $fcount || !$pcount ) {
1111                     $scheckerr++;
1112                 }
1113                 else {
1114                     $scheckok++;
1115                 }
1116
1117             }
1118             elsif ( !cmp_file( $tname, $rsp, $out ) ) {
1119                 $cmperr++;
1120             }
1121             else {
1122                 $cmpok++;
1123             }
1124             unlink $out;
1125         }
1126     }
1127     if ($outfile ne "") {
1128         print OUT "\n\necho All Tests Completed\n" unless $minimal_script;
1129         close OUT;
1130     }
1131 }
1132
1133 sub cmp_file {
1134     my ( $tname, $rsp, $tst ) = @_;
1135     my ( $rspf,    $tstf );
1136     my ( $rspline, $tstline );
1137     my $monte = 0;
1138     if ( !open( $rspf, $rsp ) ) {
1139         print STDERR "ERROR: can't open request file $rsp\n";
1140         return 0;
1141     }
1142     if ( !open( $tstf, $tst ) ) {
1143         print STDERR "ERROR: can't open output file $tst\n";
1144         return 0;
1145     }
1146     $monte = 1 if ($rsp =~ /Monte[123]/);
1147     for ( ; ; ) {
1148         $rspline = next_line($rspf);
1149         $tstline = next_line($tstf);
1150         if ( !defined($rspline) && !defined($tstline) ) {
1151             print STDERR "DEBUG: $tname file comparison OK\n" if $debug;
1152             return 1;
1153         }
1154         # Workaround for old broken DES3 MCT format which added bogus
1155         # extra lines: after [ENCRYPT] or [DECRYPT] skip until first
1156         # COUNT line.
1157         if ($monte) {
1158                 if ($rspline =~ /CRYPT/) {
1159                         do {
1160                                 $rspline = next_line($rspf);
1161                         } while (defined($rspline) && $rspline !~ /COUNT/);
1162                 }
1163                 if ($tstline =~ /CRYPT/) {
1164                         do {
1165                                 $tstline = next_line($tstf);
1166                         } while (defined($tstline) && $tstline !~ /COUNT/);
1167                 }
1168         }
1169         if ( !defined($rspline) ) {
1170             print STDERR "ERROR: $tname EOF on $rsp\n";
1171             return 0;
1172         }
1173         if ( !defined($tstline) ) {
1174             print STDERR "ERROR: $tname EOF on $tst\n";
1175             return 0;
1176         }
1177
1178         # Workaround for bug in RAND des2 test output */
1179         if ( $tstline =~ /^Key2 =/ && $rspline =~ /^Key1 =/ ) {
1180             $rspline =~ s/^Key1/Key2/;
1181         }
1182
1183         if ( $tstline ne $rspline ) {
1184             print STDERR "ERROR: $tname mismatch:\n";
1185             print STDERR "\t \"$tstline\" != \"$rspline\"\n";
1186             return 0;
1187         }
1188     }
1189     return 1;
1190 }
1191
1192 sub next_line {
1193     my ($in) = @_;
1194
1195     while (<$in>) {
1196         chomp;
1197
1198         # Delete comments
1199         s/#.*$//;
1200
1201         # Ignore blank lines
1202         next if (/^\s*$/);
1203
1204         # Translate multiple space into one
1205         s/\s+/ /g;
1206         # Delete trailing whitespace
1207         s/\s+$//;
1208         # Remove leading zeroes
1209         s/= 00/= /;
1210         # Translate to upper case
1211         return uc $_;
1212     }
1213     return undef;
1214 }