03-test_fipsinstall.t revision 1.1.1.1 1 #! /usr/bin/env perl
2 # Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
3 #
4 # Licensed under the Apache License 2.0 (the "License"). You may not use
5 # this file except in compliance with the License. You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
8
9 use strict;
10 use warnings;
11
12 use File::Spec::Functions qw(:DEFAULT abs2rel);
13 use File::Copy;
14 use OpenSSL::Glob;
15 use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file/;
16 use OpenSSL::Test::Utils;
17
18 BEGIN {
19 setup("test_fipsinstall");
20 }
21 use lib srctop_dir('Configurations');
22 use lib bldtop_dir('.');
23 use platform;
24
25 plan skip_all => "Test only supported in a fips build" if disabled("fips");
26
27 plan tests => 29;
28
29 my $infile = bldtop_file('providers', platform->dso('fips'));
30 my $fipskey = $ENV{FIPSKEY} // config('FIPSKEY') // '00';
31 my $provconf = srctop_file("test", "fips-and-base.cnf");
32
33 # Read in a text $infile and replace the regular expression in $srch with the
34 # value in $repl and output to a new file $outfile.
35 sub replace_line_file_internal {
36
37 my ($infile, $srch, $repl, $outfile) = @_;
38 my $msg;
39
40 open(my $in, "<", $infile) or return 0;
41 read($in, $msg, 1024);
42 close $in;
43
44 $msg =~ s/$srch/$repl/;
45
46 open(my $fh, ">", $outfile) or return 0;
47 print $fh $msg;
48 close $fh;
49 return 1;
50 }
51
52 # Read in the text input file 'fips.cnf'
53 # and replace a single Key = Value line with a new value in $value.
54 # OR remove the Key = Value line if the passed in $value is empty.
55 # and then output a new file $outfile.
56 # $key is the Key to find
57 sub replace_line_file {
58 my ($key, $value, $outfile) = @_;
59
60 my $srch = qr/$key\s*=\s*\S*\n/;
61 my $rep;
62 if ($value eq "") {
63 $rep = "";
64 } else {
65 $rep = "$key = $value\n";
66 }
67 return replace_line_file_internal('fips.cnf', $srch, $rep, $outfile);
68 }
69
70 # Read in the text input file 'test/fips.cnf'
71 # and replace the .cnf file used in
72 # .include fipsmodule.cnf with a new value in $value.
73 # and then output a new file $outfile.
74 # $key is the Key to find
75 sub replace_parent_line_file {
76 my ($value, $outfile) = @_;
77 my $srch = qr/fipsmodule.cnf/;
78 my $rep = "$value";
79 return replace_line_file_internal(srctop_file("test", 'fips.cnf'),
80 $srch, $rep, $outfile);
81 }
82
83 # fail if no module name
84 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module',
85 '-provider_name', 'fips',
86 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
87 '-section_name', 'fips_sect'])),
88 "fipsinstall fail");
89
90 # fail to verify if the configuration file is missing
91 ok(!run(app(['openssl', 'fipsinstall', '-in', 'dummy.tmp', '-module', $infile,
92 '-provider_name', 'fips', '-mac_name', 'HMAC',
93 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
94 '-section_name', 'fips_sect', '-verify'])),
95 "fipsinstall verify fail");
96
97
98 # output a fips.cnf file containing mac data
99 ok(run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
100 '-provider_name', 'fips', '-mac_name', 'HMAC',
101 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
102 '-section_name', 'fips_sect'])),
103 "fipsinstall");
104
105 # verify the fips.cnf file
106 ok(run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
107 '-provider_name', 'fips', '-mac_name', 'HMAC',
108 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
109 '-section_name', 'fips_sect', '-verify'])),
110 "fipsinstall verify");
111
112 ok(replace_line_file('module-mac', '', 'fips_no_module_mac.cnf')
113 && !run(app(['openssl', 'fipsinstall',
114 '-in', 'fips_no_module_mac.cnf',
115 '-module', $infile,
116 '-provider_name', 'fips', '-mac_name', 'HMAC',
117 '-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
118 '-section_name', 'fips_sect', '-verify'])),
119 "fipsinstall verify fail no module mac");
120
121 ok(replace_line_file('install-mac', '', 'fips_no_install_mac.cnf')
122 && !run(app(['openssl', 'fipsinstall',
123 '-in', 'fips_no_install_mac.cnf',
124 '-module', $infile,
125 '-provider_name', 'fips', '-mac_name', 'HMAC',
126 '-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
127 '-section_name', 'fips_sect', '-verify'])),
128 "fipsinstall verify fail no install indicator mac");
129
130 ok(replace_line_file('module-mac', '00:00:00:00:00:00',
131 'fips_bad_module_mac.cnf')
132 && !run(app(['openssl', 'fipsinstall',
133 '-in', 'fips_bad_module_mac.cnf',
134 '-module', $infile,
135 '-provider_name', 'fips', '-mac_name', 'HMAC',
136 '-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
137 '-section_name', 'fips_sect', '-verify'])),
138 "fipsinstall verify fail if invalid module integrity value");
139
140 ok(replace_line_file('install-mac', '00:00:00:00:00:00',
141 'fips_bad_install_mac.cnf')
142 && !run(app(['openssl', 'fipsinstall',
143 '-in', 'fips_bad_install_mac.cnf',
144 '-module', $infile,
145 '-provider_name', 'fips', '-mac_name', 'HMAC',
146 '-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
147 '-section_name', 'fips_sect', '-verify'])),
148 "fipsinstall verify fail if invalid install indicator integrity value");
149
150 ok(replace_line_file('install-status', 'INCORRECT_STATUS_STRING',
151 'fips_bad_indicator.cnf')
152 && !run(app(['openssl', 'fipsinstall',
153 '-in', 'fips_bad_indicator.cnf',
154 '-module', $infile,
155 '-provider_name', 'fips', '-mac_name', 'HMAC',
156 '-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
157 '-section_name', 'fips_sect', '-verify'])),
158 "fipsinstall verify fail if invalid install indicator status");
159
160 # fail to verify the fips.cnf file if a different key is used
161 ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
162 '-provider_name', 'fips', '-mac_name', 'HMAC',
163 '-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
164 '-section_name', 'fips_sect', '-verify'])),
165 "fipsinstall verify fail bad key");
166
167 # fail to verify the fips.cnf file if a different mac digest is used
168 ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
169 '-provider_name', 'fips', '-mac_name', 'HMAC',
170 '-macopt', 'digest:SHA512', '-macopt', "hexkey:$fipskey",
171 '-section_name', 'fips_sect', '-verify'])),
172 "fipsinstall verify fail incorrect digest");
173
174 # corrupt the module hmac
175 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
176 '-provider_name', 'fips', '-mac_name', 'HMAC',
177 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
178 '-section_name', 'fips_sect', '-corrupt_desc', 'HMAC'])),
179 "fipsinstall fails when the module integrity is corrupted");
180
181 # corrupt the first digest
182 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
183 '-provider_name', 'fips', '-mac_name', 'HMAC',
184 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
185 '-section_name', 'fips_sect', '-corrupt_desc', 'SHA1'])),
186 "fipsinstall fails when the digest result is corrupted");
187
188 # corrupt another digest
189 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
190 '-provider_name', 'fips', '-mac_name', 'HMAC',
191 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
192 '-section_name', 'fips_sect', '-corrupt_desc', 'SHA3'])),
193 "fipsinstall fails when the digest result is corrupted");
194
195 # corrupt cipher encrypt test
196 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
197 '-provider_name', 'fips', '-mac_name', 'HMAC',
198 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
199 '-section_name', 'fips_sect', '-corrupt_desc', 'AES_GCM'])),
200 "fipsinstall fails when the AES_GCM result is corrupted");
201
202 # corrupt cipher decrypt test
203 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
204 '-provider_name', 'fips', '-mac_name', 'HMAC',
205 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
206 '-section_name', 'fips_sect', '-corrupt_desc', 'AES_ECB_Decrypt'])),
207 "fipsinstall fails when the AES_ECB result is corrupted");
208
209 # corrupt DRBG
210 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
211 '-provider_name', 'fips', '-mac_name', 'HMAC',
212 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
213 '-section_name', 'fips_sect', '-corrupt_desc', 'CTR'])),
214 "fipsinstall fails when the DRBG CTR result is corrupted");
215
216 # corrupt a KAS test
217 SKIP: {
218 skip "Skipping KAS DH corruption test because of no dh in this build", 1
219 if disabled("dh");
220
221 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
222 '-provider_name', 'fips', '-mac_name', 'HMAC',
223 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
224 '-section_name', 'fips_sect',
225 '-corrupt_desc', 'DH',
226 '-corrupt_type', 'KAT_KA'])),
227 "fipsinstall fails when the kas result is corrupted");
228 }
229
230 # corrupt a Signature test
231 SKIP: {
232 skip "Skipping Signature DSA corruption test because of no dsa in this build", 1
233 if disabled("dsa");
234
235 run(test(["fips_version_test", "-config", $provconf, "<3.1.0"]),
236 capture => 1, statusvar => \my $exit);
237 skip "FIPS provider version is too new for PCT DSA signature test", 1
238 if !$exit;
239
240 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
241 '-provider_name', 'fips', '-mac_name', 'HMAC',
242 '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
243 '-section_name', 'fips_sect',
244 '-corrupt_desc', 'DSA',
245 '-corrupt_type', 'PCT_Signature'])),
246 "fipsinstall fails when the signature result is corrupted");
247 }
248
249 # corrupt an Asymmetric cipher test
250 SKIP: {
251 skip "Skipping Asymmetric RSA corruption test because of no rsa in this build", 1
252 if disabled("rsa");
253 ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
254 '-corrupt_desc', 'RSA_Encrypt',
255 '-corrupt_type', 'KAT_AsymmetricCipher'])),
256 "fipsinstall fails when the asymmetric cipher result is corrupted");
257 }
258
259 # 'local' ensures that this change is only done in this file.
260 local $ENV{OPENSSL_CONF_INCLUDE} = abs2rel(curdir());
261
262 ok(replace_parent_line_file('fips.cnf', 'fips_parent.cnf')
263 && run(app(['openssl', 'fipsinstall', '-config', 'fips_parent.cnf'])),
264 "verify fips provider loads from a configuration file");
265
266 ok(replace_parent_line_file('fips_no_module_mac.cnf',
267 'fips_parent_no_module_mac.cnf')
268 && !run(app(['openssl', 'fipsinstall',
269 '-config', 'fips_parent_no_module_mac.cnf'])),
270 "verify load config fail no module mac");
271
272 ok(replace_parent_line_file('fips_no_install_mac.cnf',
273 'fips_parent_no_install_mac.cnf')
274 && !run(app(['openssl', 'fipsinstall',
275 '-config', 'fips_parent_no_install_mac.cnf'])),
276 "verify load config fail no install mac");
277
278 ok(replace_parent_line_file('fips_bad_indicator.cnf',
279 'fips_parent_bad_indicator.cnf')
280 && !run(app(['openssl', 'fipsinstall',
281 '-config', 'fips_parent_bad_indicator.cnf'])),
282 "verify load config fail bad indicator");
283
284
285 ok(replace_parent_line_file('fips_bad_install_mac.cnf',
286 'fips_parent_bad_install_mac.cnf')
287 && !run(app(['openssl', 'fipsinstall',
288 '-config', 'fips_parent_bad_install_mac.cnf'])),
289 "verify load config fail bad install mac");
290
291 ok(replace_parent_line_file('fips_bad_module_mac.cnf',
292 'fips_parent_bad_module_mac.cnf')
293 && !run(app(['openssl', 'fipsinstall',
294 '-config', 'fips_parent_bad_module_mac.cnf'])),
295 "verify load config fail bad module mac");
296
297
298 my $stconf = "fipsmodule_selftest.cnf";
299
300 ok(run(app(['openssl', 'fipsinstall', '-out', $stconf,
301 '-module', $infile, '-self_test_onload'])),
302 "fipsinstall config saved without self test indicator");
303
304 ok(!run(app(['openssl', 'fipsinstall', '-in', $stconf,
305 '-module', $infile, '-verify'])),
306 "fipsinstall config verify fails without self test indicator");
307
308 ok(run(app(['openssl', 'fipsinstall', '-in', $stconf,
309 '-module', $infile, '-self_test_onload', '-verify'])),
310 "fipsinstall config verify passes when self test indicator is not present");
311