1 /*
2 * Copyright 2019-2024 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
10 #include <openssl/evp.h>
11 #include <openssl/err.h>
12 #include <openssl/provider.h>
13 #include <openssl/params.h>
14 #include <openssl/fips_names.h>
15 #include <openssl/core_names.h>
16 #include <openssl/self_test.h>
17 #include <openssl/fipskey.h>
18 #include "apps.h"
19 #include "progs.h"
20
21 #define BUFSIZE 4096
22
23 /* Configuration file values */
24 #define VERSION_KEY "version"
25 #define VERSION_VAL "1"
26 #define INSTALL_STATUS_VAL "INSTALL_SELF_TEST_KATS_RUN"
27
28 static OSSL_CALLBACK self_test_events;
29 static char *self_test_corrupt_desc = NULL;
30 static char *self_test_corrupt_type = NULL;
31 static int self_test_log = 1;
32 static int quiet = 0;
33
34 typedef enum OPTION_choice {
35 OPT_COMMON,
36 OPT_IN,
37 OPT_OUT,
38 OPT_MODULE,
39 OPT_PEDANTIC,
40 OPT_PROV_NAME,
41 OPT_SECTION_NAME,
42 OPT_MAC_NAME,
43 OPT_MACOPT,
44 OPT_VERIFY,
45 OPT_NO_LOG,
46 OPT_CORRUPT_DESC,
47 OPT_CORRUPT_TYPE,
48 OPT_QUIET,
49 OPT_CONFIG,
50 OPT_NO_CONDITIONAL_ERRORS,
51 OPT_NO_SECURITY_CHECKS,
52 OPT_TLS_PRF_EMS_CHECK,
53 OPT_NO_SHORT_MAC,
54 OPT_DISALLOW_PKCS15_PADDING,
55 OPT_RSA_PSS_SALTLEN_CHECK,
56 OPT_DISALLOW_SIGNATURE_X931_PADDING,
57 OPT_HMAC_KEY_CHECK,
58 OPT_KMAC_KEY_CHECK,
59 OPT_DISALLOW_DRGB_TRUNC_DIGEST,
60 OPT_SIGNATURE_DIGEST_CHECK,
61 OPT_HKDF_DIGEST_CHECK,
62 OPT_TLS13_KDF_DIGEST_CHECK,
63 OPT_TLS1_PRF_DIGEST_CHECK,
64 OPT_SSHKDF_DIGEST_CHECK,
65 OPT_SSKDF_DIGEST_CHECK,
66 OPT_X963KDF_DIGEST_CHECK,
67 OPT_DISALLOW_DSA_SIGN,
68 OPT_DISALLOW_TDES_ENCRYPT,
69 OPT_HKDF_KEY_CHECK,
70 OPT_KBKDF_KEY_CHECK,
71 OPT_TLS13_KDF_KEY_CHECK,
72 OPT_TLS1_PRF_KEY_CHECK,
73 OPT_SSHKDF_KEY_CHECK,
74 OPT_SSKDF_KEY_CHECK,
75 OPT_X963KDF_KEY_CHECK,
76 OPT_X942KDF_KEY_CHECK,
77 OPT_NO_PBKDF2_LOWER_BOUND_CHECK,
78 OPT_ECDH_COFACTOR_CHECK,
79 OPT_SELF_TEST_ONLOAD,
80 OPT_SELF_TEST_ONINSTALL
81 } OPTION_CHOICE;
82
83 const OPTIONS fipsinstall_options[] = {
84 OPT_SECTION("General"),
85 { "help", OPT_HELP, '-', "Display this summary" },
86 { "pedantic", OPT_PEDANTIC, '-', "Set options for strict FIPS compliance" },
87 { "verify", OPT_VERIFY, '-',
88 "Verify a config file instead of generating one" },
89 { "module", OPT_MODULE, '<', "File name of the provider module" },
90 { "provider_name", OPT_PROV_NAME, 's', "FIPS provider name" },
91 { "section_name", OPT_SECTION_NAME, 's',
92 "FIPS Provider config section name (optional)" },
93 { "no_conditional_errors", OPT_NO_CONDITIONAL_ERRORS, '-',
94 "Disable the ability of the fips module to enter an error state if"
95 " any conditional self tests fail" },
96 { "no_security_checks", OPT_NO_SECURITY_CHECKS, '-',
97 "Disable the run-time FIPS security checks in the module" },
98 { "self_test_onload", OPT_SELF_TEST_ONLOAD, '-',
99 "Forces self tests to always run on module load" },
100 { "self_test_oninstall", OPT_SELF_TEST_ONINSTALL, '-',
101 "Forces self tests to run once on module installation" },
102 { "ems_check", OPT_TLS_PRF_EMS_CHECK, '-',
103 "Enable the run-time FIPS check for EMS during TLS1_PRF" },
104 { "no_short_mac", OPT_NO_SHORT_MAC, '-', "Disallow short MAC output" },
105 { "no_drbg_truncated_digests", OPT_DISALLOW_DRGB_TRUNC_DIGEST, '-',
106 "Disallow truncated digests with Hash and HMAC DRBGs" },
107 { "signature_digest_check", OPT_SIGNATURE_DIGEST_CHECK, '-',
108 "Enable checking for approved digests for signatures" },
109 { "hmac_key_check", OPT_HMAC_KEY_CHECK, '-', "Enable key check for HMAC" },
110 { "kmac_key_check", OPT_KMAC_KEY_CHECK, '-', "Enable key check for KMAC" },
111 { "hkdf_digest_check", OPT_HKDF_DIGEST_CHECK, '-',
112 "Enable digest check for HKDF" },
113 { "tls13_kdf_digest_check", OPT_TLS13_KDF_DIGEST_CHECK, '-',
114 "Enable digest check for TLS13-KDF" },
115 { "tls1_prf_digest_check", OPT_TLS1_PRF_DIGEST_CHECK, '-',
116 "Enable digest check for TLS1-PRF" },
117 { "sshkdf_digest_check", OPT_SSHKDF_DIGEST_CHECK, '-',
118 "Enable digest check for SSHKDF" },
119 { "sskdf_digest_check", OPT_SSKDF_DIGEST_CHECK, '-',
120 "Enable digest check for SSKDF" },
121 { "x963kdf_digest_check", OPT_X963KDF_DIGEST_CHECK, '-',
122 "Enable digest check for X963KDF" },
123 { "dsa_sign_disabled", OPT_DISALLOW_DSA_SIGN, '-',
124 "Disallow DSA signing" },
125 { "tdes_encrypt_disabled", OPT_DISALLOW_TDES_ENCRYPT, '-',
126 "Disallow Triple-DES encryption" },
127 { "rsa_pkcs15_padding_disabled", OPT_DISALLOW_PKCS15_PADDING, '-',
128 "Disallow PKCS#1 version 1.5 padding for RSA encryption" },
129 { "rsa_pss_saltlen_check", OPT_RSA_PSS_SALTLEN_CHECK, '-',
130 "Enable salt length check for RSA-PSS signature operations" },
131 { "rsa_sign_x931_disabled", OPT_DISALLOW_SIGNATURE_X931_PADDING, '-',
132 "Disallow X931 Padding for RSA signing" },
133 { "hkdf_key_check", OPT_HKDF_KEY_CHECK, '-',
134 "Enable key check for HKDF" },
135 { "kbkdf_key_check", OPT_KBKDF_KEY_CHECK, '-',
136 "Enable key check for KBKDF" },
137 { "tls13_kdf_key_check", OPT_TLS13_KDF_KEY_CHECK, '-',
138 "Enable key check for TLS13-KDF" },
139 { "tls1_prf_key_check", OPT_TLS1_PRF_KEY_CHECK, '-',
140 "Enable key check for TLS1-PRF" },
141 { "sshkdf_key_check", OPT_SSHKDF_KEY_CHECK, '-',
142 "Enable key check for SSHKDF" },
143 { "sskdf_key_check", OPT_SSKDF_KEY_CHECK, '-',
144 "Enable key check for SSKDF" },
145 { "x963kdf_key_check", OPT_X963KDF_KEY_CHECK, '-',
146 "Enable key check for X963KDF" },
147 { "x942kdf_key_check", OPT_X942KDF_KEY_CHECK, '-',
148 "Enable key check for X942KDF" },
149 { "no_pbkdf2_lower_bound_check", OPT_NO_PBKDF2_LOWER_BOUND_CHECK, '-',
150 "Disable lower bound check for PBKDF2" },
151 { "ecdh_cofactor_check", OPT_ECDH_COFACTOR_CHECK, '-',
152 "Enable Cofactor check for ECDH" },
153 OPT_SECTION("Input"),
154 { "in", OPT_IN, '<', "Input config file, used when verifying" },
155
156 OPT_SECTION("Output"),
157 { "out", OPT_OUT, '>', "Output config file, used when generating" },
158 { "mac_name", OPT_MAC_NAME, 's', "MAC name" },
159 { "macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form." },
160 { OPT_MORE_STR, 0, 0, "See 'PARAMETER NAMES' in the EVP_MAC_ docs" },
161 { "noout", OPT_NO_LOG, '-', "Disable logging of self test events" },
162 { "corrupt_desc", OPT_CORRUPT_DESC, 's', "Corrupt a self test by description" },
163 { "corrupt_type", OPT_CORRUPT_TYPE, 's', "Corrupt a self test by type" },
164 { "config", OPT_CONFIG, '<', "The parent config to verify" },
165 { "quiet", OPT_QUIET, '-', "No messages, just exit status" },
166 { NULL }
167 };
168
169 typedef struct {
170 unsigned int self_test_onload : 1;
171 unsigned int conditional_errors : 1;
172 unsigned int security_checks : 1;
173 unsigned int hmac_key_check : 1;
174 unsigned int kmac_key_check : 1;
175 unsigned int tls_prf_ems_check : 1;
176 unsigned int no_short_mac : 1;
177 unsigned int drgb_no_trunc_dgst : 1;
178 unsigned int signature_digest_check : 1;
179 unsigned int hkdf_digest_check : 1;
180 unsigned int tls13_kdf_digest_check : 1;
181 unsigned int tls1_prf_digest_check : 1;
182 unsigned int sshkdf_digest_check : 1;
183 unsigned int sskdf_digest_check : 1;
184 unsigned int x963kdf_digest_check : 1;
185 unsigned int dsa_sign_disabled : 1;
186 unsigned int tdes_encrypt_disabled : 1;
187 unsigned int rsa_pkcs15_padding_disabled : 1;
188 unsigned int rsa_pss_saltlen_check : 1;
189 unsigned int sign_x931_padding_disabled : 1;
190 unsigned int hkdf_key_check : 1;
191 unsigned int kbkdf_key_check : 1;
192 unsigned int tls13_kdf_key_check : 1;
193 unsigned int tls1_prf_key_check : 1;
194 unsigned int sshkdf_key_check : 1;
195 unsigned int sskdf_key_check : 1;
196 unsigned int x963kdf_key_check : 1;
197 unsigned int x942kdf_key_check : 1;
198 unsigned int pbkdf2_lower_bound_check : 1;
199 unsigned int ecdh_cofactor_check : 1;
200 } FIPS_OPTS;
201
202 /* Pedantic FIPS compliance */
203 static const FIPS_OPTS pedantic_opts = {
204 1, /* self_test_onload */
205 1, /* conditional_errors */
206 1, /* security_checks */
207 1, /* hmac_key_check */
208 1, /* kmac_key_check */
209 1, /* tls_prf_ems_check */
210 1, /* no_short_mac */
211 1, /* drgb_no_trunc_dgst */
212 1, /* signature_digest_check */
213 1, /* hkdf_digest_check */
214 1, /* tls13_kdf_digest_check */
215 1, /* tls1_prf_digest_check */
216 1, /* sshkdf_digest_check */
217 1, /* sskdf_digest_check */
218 1, /* x963kdf_digest_check */
219 1, /* dsa_sign_disabled */
220 1, /* tdes_encrypt_disabled */
221 1, /* rsa_pkcs15_padding_disabled */
222 1, /* rsa_pss_saltlen_check */
223 1, /* sign_x931_padding_disabled */
224 1, /* hkdf_key_check */
225 1, /* kbkdf_key_check */
226 1, /* tls13_kdf_key_check */
227 1, /* tls1_prf_key_check */
228 1, /* sshkdf_key_check */
229 1, /* sskdf_key_check */
230 1, /* x963kdf_key_check */
231 1, /* x942kdf_key_check */
232 1, /* pbkdf2_lower_bound_check */
233 1, /* ecdh_cofactor_check */
234 };
235
236 /* Default FIPS settings for backward compatibility */
237 static FIPS_OPTS fips_opts = {
238 1, /* self_test_onload */
239 1, /* conditional_errors */
240 1, /* security_checks */
241 0, /* hmac_key_check */
242 0, /* kmac_key_check */
243 0, /* tls_prf_ems_check */
244 0, /* no_short_mac */
245 0, /* drgb_no_trunc_dgst */
246 0, /* signature_digest_check */
247 0, /* hkdf_digest_check */
248 0, /* tls13_kdf_digest_check */
249 0, /* tls1_prf_digest_check */
250 0, /* sshkdf_digest_check */
251 0, /* sskdf_digest_check */
252 0, /* x963kdf_digest_check */
253 0, /* dsa_sign_disabled */
254 0, /* tdes_encrypt_disabled */
255 0, /* rsa_pkcs15_padding_disabled */
256 0, /* rsa_pss_saltlen_check */
257 0, /* sign_x931_padding_disabled */
258 0, /* hkdf_key_check */
259 0, /* kbkdf_key_check */
260 0, /* tls13_kdf_key_check */
261 0, /* tls1_prf_key_check */
262 0, /* sshkdf_key_check */
263 0, /* sskdf_key_check */
264 0, /* x963kdf_key_check */
265 0, /* x942kdf_key_check */
266 1, /* pbkdf2_lower_bound_check */
267 0, /* ecdh_cofactor_check */
268 };
269
check_non_pedantic_fips(int pedantic,const char * name)270 static int check_non_pedantic_fips(int pedantic, const char *name)
271 {
272 if (pedantic) {
273 BIO_printf(bio_err, "Cannot specify -%s after -pedantic\n", name);
274 return 0;
275 }
276 return 1;
277 }
278
do_mac(EVP_MAC_CTX * ctx,unsigned char * tmp,BIO * in,unsigned char * out,size_t * out_len)279 static int do_mac(EVP_MAC_CTX *ctx, unsigned char *tmp, BIO *in,
280 unsigned char *out, size_t *out_len)
281 {
282 int ret = 0;
283 int i;
284 size_t outsz = *out_len;
285
286 if (!EVP_MAC_init(ctx, NULL, 0, NULL))
287 goto err;
288 if (EVP_MAC_CTX_get_mac_size(ctx) > outsz)
289 goto end;
290 while ((i = BIO_read(in, (char *)tmp, BUFSIZE)) != 0) {
291 if (i < 0 || !EVP_MAC_update(ctx, tmp, i))
292 goto err;
293 }
294 end:
295 if (!EVP_MAC_final(ctx, out, out_len, outsz))
296 goto err;
297 ret = 1;
298 err:
299 return ret;
300 }
301
load_fips_prov_and_run_self_test(const char * prov_name,int * is_fips_140_2_prov)302 static int load_fips_prov_and_run_self_test(const char *prov_name,
303 int *is_fips_140_2_prov)
304 {
305 int ret = 0;
306 OSSL_PROVIDER *prov = NULL;
307 OSSL_PARAM params[4], *p = params;
308 char *name = "", *vers = "", *build = "";
309
310 prov = OSSL_PROVIDER_load(NULL, prov_name);
311 if (prov == NULL) {
312 BIO_printf(bio_err, "Failed to load FIPS module\n");
313 goto end;
314 }
315 if (!quiet) {
316 *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME,
317 &name, sizeof(name));
318 *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
319 &vers, sizeof(vers));
320 *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO,
321 &build, sizeof(build));
322 *p = OSSL_PARAM_construct_end();
323 if (!OSSL_PROVIDER_get_params(prov, params)) {
324 BIO_printf(bio_err, "Failed to query FIPS module parameters\n");
325 goto end;
326 }
327 if (OSSL_PARAM_modified(params))
328 BIO_printf(bio_err, "\t%-10s\t%s\n", "name:", name);
329 if (OSSL_PARAM_modified(params + 1))
330 BIO_printf(bio_err, "\t%-10s\t%s\n", "version:", vers);
331 if (OSSL_PARAM_modified(params + 2))
332 BIO_printf(bio_err, "\t%-10s\t%s\n", "build:", build);
333 } else {
334 *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
335 &vers, sizeof(vers));
336 *p = OSSL_PARAM_construct_end();
337 if (!OSSL_PROVIDER_get_params(prov, params)) {
338 BIO_printf(bio_err, "Failed to query FIPS module parameters\n");
339 goto end;
340 }
341 }
342 *is_fips_140_2_prov = (strncmp("3.0.", vers, 4) == 0);
343 ret = 1;
344 end:
345 OSSL_PROVIDER_unload(prov);
346 return ret;
347 }
348
print_mac(BIO * bio,const char * label,const unsigned char * mac,size_t len)349 static int print_mac(BIO *bio, const char *label, const unsigned char *mac,
350 size_t len)
351 {
352 int ret;
353 char *hexstr = NULL;
354
355 hexstr = OPENSSL_buf2hexstr(mac, (long)len);
356 if (hexstr == NULL)
357 return 0;
358 ret = BIO_printf(bio, "%s = %s\n", label, hexstr);
359 OPENSSL_free(hexstr);
360 return ret;
361 }
362
write_config_header(BIO * out,const char * prov_name,const char * section)363 static int write_config_header(BIO *out, const char *prov_name,
364 const char *section)
365 {
366 return BIO_printf(out, "openssl_conf = openssl_init\n\n")
367 && BIO_printf(out, "[openssl_init]\n")
368 && BIO_printf(out, "providers = provider_section\n\n")
369 && BIO_printf(out, "[provider_section]\n")
370 && BIO_printf(out, "%s = %s\n\n", prov_name, section);
371 }
372
373 /*
374 * Outputs a fips related config file that contains entries for the fips
375 * module checksum, installation indicator checksum and the options
376 * conditional_errors and security_checks.
377 *
378 * Returns 1 if the config file is written otherwise it returns 0 on error.
379 */
write_config_fips_section(BIO * out,const char * section,unsigned char * module_mac,size_t module_mac_len,const FIPS_OPTS * opts,unsigned char * install_mac,size_t install_mac_len)380 static int write_config_fips_section(BIO *out, const char *section,
381 unsigned char *module_mac,
382 size_t module_mac_len,
383 const FIPS_OPTS *opts,
384 unsigned char *install_mac,
385 size_t install_mac_len)
386 {
387 int ret = 0;
388
389 if (BIO_printf(out, "[%s]\n", section) <= 0
390 || BIO_printf(out, "activate = 1\n") <= 0
391 || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
392 VERSION_VAL)
393 <= 0
394 || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS,
395 opts->conditional_errors ? "1" : "0")
396 <= 0
397 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SECURITY_CHECKS,
398 opts->security_checks ? "1" : "0")
399 <= 0
400 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HMAC_KEY_CHECK,
401 opts->hmac_key_check ? "1" : "0")
402 <= 0
403 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_KMAC_KEY_CHECK,
404 opts->kmac_key_check ? "1" : "0")
405 <= 0
406 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK,
407 opts->tls_prf_ems_check ? "1" : "0")
408 <= 0
409 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_NO_SHORT_MAC,
410 opts->no_short_mac ? "1" : "0")
411 <= 0
412 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST,
413 opts->drgb_no_trunc_dgst ? "1" : "0")
414 <= 0
415 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SIGNATURE_DIGEST_CHECK,
416 opts->signature_digest_check ? "1" : "0")
417 <= 0
418 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HKDF_DIGEST_CHECK,
419 opts->hkdf_digest_check ? "1" : "0")
420 <= 0
421 || BIO_printf(out, "%s = %s\n",
422 OSSL_PROV_PARAM_TLS13_KDF_DIGEST_CHECK,
423 opts->tls13_kdf_digest_check ? "1" : "0")
424 <= 0
425 || BIO_printf(out, "%s = %s\n",
426 OSSL_PROV_PARAM_TLS1_PRF_DIGEST_CHECK,
427 opts->tls1_prf_digest_check ? "1" : "0")
428 <= 0
429 || BIO_printf(out, "%s = %s\n",
430 OSSL_PROV_PARAM_SSHKDF_DIGEST_CHECK,
431 opts->sshkdf_digest_check ? "1" : "0")
432 <= 0
433 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSKDF_DIGEST_CHECK,
434 opts->sskdf_digest_check ? "1" : "0")
435 <= 0
436 || BIO_printf(out, "%s = %s\n",
437 OSSL_PROV_PARAM_X963KDF_DIGEST_CHECK,
438 opts->x963kdf_digest_check ? "1" : "0")
439 <= 0
440 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_DSA_SIGN_DISABLED,
441 opts->dsa_sign_disabled ? "1" : "0")
442 <= 0
443 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED,
444 opts->tdes_encrypt_disabled ? "1" : "0")
445 <= 0
446 || BIO_printf(out, "%s = %s\n",
447 OSSL_PROV_PARAM_RSA_PKCS15_PAD_DISABLED,
448 opts->rsa_pkcs15_padding_disabled ? "1" : "0")
449 <= 0
450 || BIO_printf(out, "%s = %s\n",
451 OSSL_PROV_PARAM_RSA_PSS_SALTLEN_CHECK,
452 opts->rsa_pss_saltlen_check ? "1" : "0")
453 <= 0
454 || BIO_printf(out, "%s = %s\n",
455 OSSL_PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED,
456 opts->sign_x931_padding_disabled ? "1" : "0")
457 <= 0
458 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HKDF_KEY_CHECK,
459 opts->hkdf_key_check ? "1" : "0")
460 <= 0
461 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_KBKDF_KEY_CHECK,
462 opts->kbkdf_key_check ? "1" : "0")
463 <= 0
464 || BIO_printf(out, "%s = %s\n",
465 OSSL_PROV_PARAM_TLS13_KDF_KEY_CHECK,
466 opts->tls13_kdf_key_check ? "1" : "0")
467 <= 0
468 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TLS1_PRF_KEY_CHECK,
469 opts->tls1_prf_key_check ? "1" : "0")
470 <= 0
471 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSHKDF_KEY_CHECK,
472 opts->sshkdf_key_check ? "1" : "0")
473 <= 0
474 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSKDF_KEY_CHECK,
475 opts->sskdf_key_check ? "1" : "0")
476 <= 0
477 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_X963KDF_KEY_CHECK,
478 opts->x963kdf_key_check ? "1" : "0")
479 <= 0
480 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_X942KDF_KEY_CHECK,
481 opts->x942kdf_key_check ? "1" : "0")
482 <= 0
483 || BIO_printf(out, "%s = %s\n",
484 OSSL_PROV_PARAM_PBKDF2_LOWER_BOUND_CHECK,
485 opts->pbkdf2_lower_bound_check ? "1" : "0")
486 <= 0
487 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_ECDH_COFACTOR_CHECK,
488 opts->ecdh_cofactor_check ? "1" : "0")
489 <= 0
490 || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
491 module_mac_len))
492 goto end;
493
494 if (install_mac != NULL
495 && install_mac_len > 0
496 && opts->self_test_onload == 0) {
497 if (!print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac,
498 install_mac_len)
499 || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_STATUS,
500 INSTALL_STATUS_VAL)
501 <= 0)
502 goto end;
503 }
504 ret = 1;
505 end:
506 return ret;
507 }
508
generate_config_and_load(const char * prov_name,const char * section,unsigned char * module_mac,size_t module_mac_len,const FIPS_OPTS * opts)509 static CONF *generate_config_and_load(const char *prov_name,
510 const char *section,
511 unsigned char *module_mac,
512 size_t module_mac_len,
513 const FIPS_OPTS *opts)
514 {
515 BIO *mem_bio = NULL;
516 CONF *conf = NULL;
517
518 mem_bio = BIO_new(BIO_s_mem());
519 if (mem_bio == NULL)
520 return 0;
521 if (!write_config_header(mem_bio, prov_name, section)
522 || !write_config_fips_section(mem_bio, section,
523 module_mac, module_mac_len,
524 opts, NULL, 0))
525 goto end;
526
527 conf = app_load_config_bio(mem_bio, NULL);
528 if (conf == NULL)
529 goto end;
530
531 if (CONF_modules_load(conf, NULL, 0) <= 0)
532 goto end;
533 BIO_free(mem_bio);
534 return conf;
535 end:
536 NCONF_free(conf);
537 BIO_free(mem_bio);
538 return NULL;
539 }
540
free_config_and_unload(CONF * conf)541 static void free_config_and_unload(CONF *conf)
542 {
543 if (conf != NULL) {
544 NCONF_free(conf);
545 CONF_modules_unload(1);
546 }
547 }
548
verify_module_load(const char * parent_config_file)549 static int verify_module_load(const char *parent_config_file)
550 {
551 return OSSL_LIB_CTX_load_config(NULL, parent_config_file);
552 }
553
554 /*
555 * Returns 1 if the config file entries match the passed in module_mac and
556 * install_mac values, otherwise it returns 0.
557 */
verify_config(const char * infile,const char * section,unsigned char * module_mac,size_t module_mac_len,unsigned char * install_mac,size_t install_mac_len)558 static int verify_config(const char *infile, const char *section,
559 unsigned char *module_mac, size_t module_mac_len,
560 unsigned char *install_mac, size_t install_mac_len)
561 {
562 int ret = 0;
563 char *s = NULL;
564 unsigned char *buf1 = NULL, *buf2 = NULL;
565 long len;
566 CONF *conf = NULL;
567
568 /* read in the existing values and check they match the saved values */
569 conf = app_load_config(infile);
570 if (conf == NULL)
571 goto end;
572
573 s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_VERSION);
574 if (s == NULL || strcmp(s, VERSION_VAL) != 0) {
575 BIO_printf(bio_err, "version not found\n");
576 goto end;
577 }
578 s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_MODULE_MAC);
579 if (s == NULL) {
580 BIO_printf(bio_err, "Module integrity MAC not found\n");
581 goto end;
582 }
583 buf1 = OPENSSL_hexstr2buf(s, &len);
584 if (buf1 == NULL
585 || (size_t)len != module_mac_len
586 || memcmp(module_mac, buf1, module_mac_len) != 0) {
587 BIO_printf(bio_err, "Module integrity mismatch\n");
588 goto end;
589 }
590 if (install_mac != NULL && install_mac_len > 0) {
591 s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_STATUS);
592 if (s == NULL || strcmp(s, INSTALL_STATUS_VAL) != 0) {
593 BIO_printf(bio_err, "install status not found\n");
594 goto end;
595 }
596 s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_MAC);
597 if (s == NULL) {
598 BIO_printf(bio_err, "Install indicator MAC not found\n");
599 goto end;
600 }
601 buf2 = OPENSSL_hexstr2buf(s, &len);
602 if (buf2 == NULL
603 || (size_t)len != install_mac_len
604 || memcmp(install_mac, buf2, install_mac_len) != 0) {
605 BIO_printf(bio_err, "Install indicator status mismatch\n");
606 goto end;
607 }
608 }
609 ret = 1;
610 end:
611 OPENSSL_free(buf1);
612 OPENSSL_free(buf2);
613 NCONF_free(conf);
614 return ret;
615 }
616
fipsinstall_main(int argc,char ** argv)617 int fipsinstall_main(int argc, char **argv)
618 {
619 int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, pedantic = 0;
620 int is_fips_140_2_prov = 0, set_selftest_onload_option = 0;
621 const char *section_name = "fips_sect";
622 const char *mac_name = "HMAC";
623 const char *prov_name = "fips";
624 BIO *module_bio = NULL, *mem_bio = NULL, *fout = NULL;
625 char *in_fname = NULL, *out_fname = NULL, *prog;
626 char *module_fname = NULL, *parent_config = NULL, *module_path = NULL;
627 const char *tail;
628 EVP_MAC_CTX *ctx = NULL, *ctx2 = NULL;
629 STACK_OF(OPENSSL_STRING) *opts = NULL;
630 OPTION_CHOICE o;
631 unsigned char *read_buffer = NULL;
632 unsigned char module_mac[EVP_MAX_MD_SIZE];
633 size_t module_mac_len = EVP_MAX_MD_SIZE;
634 unsigned char install_mac[EVP_MAX_MD_SIZE];
635 size_t install_mac_len = EVP_MAX_MD_SIZE;
636 EVP_MAC *mac = NULL;
637 CONF *conf = NULL;
638
639 if ((opts = sk_OPENSSL_STRING_new_null()) == NULL)
640 goto end;
641
642 prog = opt_init(argc, argv, fipsinstall_options);
643 while ((o = opt_next()) != OPT_EOF) {
644 switch (o) {
645 case OPT_EOF:
646 case OPT_ERR:
647 opthelp:
648 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
649 goto cleanup;
650 case OPT_HELP:
651 opt_help(fipsinstall_options);
652 ret = 0;
653 goto end;
654 case OPT_IN:
655 in_fname = opt_arg();
656 break;
657 case OPT_OUT:
658 out_fname = opt_arg();
659 break;
660 case OPT_PEDANTIC:
661 fips_opts = pedantic_opts;
662 pedantic = 1;
663 break;
664 case OPT_NO_CONDITIONAL_ERRORS:
665 if (!check_non_pedantic_fips(pedantic, "no_conditional_errors"))
666 goto end;
667 fips_opts.conditional_errors = 0;
668 break;
669 case OPT_NO_SECURITY_CHECKS:
670 if (!check_non_pedantic_fips(pedantic, "no_security_checks"))
671 goto end;
672 fips_opts.security_checks = 0;
673 break;
674 case OPT_HMAC_KEY_CHECK:
675 fips_opts.hmac_key_check = 1;
676 break;
677 case OPT_KMAC_KEY_CHECK:
678 fips_opts.kmac_key_check = 1;
679 break;
680 case OPT_TLS_PRF_EMS_CHECK:
681 fips_opts.tls_prf_ems_check = 1;
682 break;
683 case OPT_NO_SHORT_MAC:
684 fips_opts.no_short_mac = 1;
685 break;
686 case OPT_DISALLOW_DRGB_TRUNC_DIGEST:
687 fips_opts.drgb_no_trunc_dgst = 1;
688 break;
689 case OPT_SIGNATURE_DIGEST_CHECK:
690 fips_opts.signature_digest_check = 1;
691 break;
692 case OPT_HKDF_DIGEST_CHECK:
693 fips_opts.hkdf_digest_check = 1;
694 break;
695 case OPT_TLS13_KDF_DIGEST_CHECK:
696 fips_opts.tls13_kdf_digest_check = 1;
697 break;
698 case OPT_TLS1_PRF_DIGEST_CHECK:
699 fips_opts.tls1_prf_digest_check = 1;
700 break;
701 case OPT_SSHKDF_DIGEST_CHECK:
702 fips_opts.sshkdf_digest_check = 1;
703 break;
704 case OPT_SSKDF_DIGEST_CHECK:
705 fips_opts.sskdf_digest_check = 1;
706 break;
707 case OPT_X963KDF_DIGEST_CHECK:
708 fips_opts.x963kdf_digest_check = 1;
709 break;
710 case OPT_DISALLOW_DSA_SIGN:
711 fips_opts.dsa_sign_disabled = 1;
712 break;
713 case OPT_DISALLOW_TDES_ENCRYPT:
714 fips_opts.tdes_encrypt_disabled = 1;
715 break;
716 case OPT_RSA_PSS_SALTLEN_CHECK:
717 fips_opts.rsa_pss_saltlen_check = 1;
718 break;
719 case OPT_DISALLOW_SIGNATURE_X931_PADDING:
720 fips_opts.sign_x931_padding_disabled = 1;
721 break;
722 case OPT_DISALLOW_PKCS15_PADDING:
723 fips_opts.rsa_pkcs15_padding_disabled = 1;
724 break;
725 case OPT_HKDF_KEY_CHECK:
726 fips_opts.hkdf_key_check = 1;
727 break;
728 case OPT_KBKDF_KEY_CHECK:
729 fips_opts.kbkdf_key_check = 1;
730 break;
731 case OPT_TLS13_KDF_KEY_CHECK:
732 fips_opts.tls13_kdf_key_check = 1;
733 break;
734 case OPT_TLS1_PRF_KEY_CHECK:
735 fips_opts.tls1_prf_key_check = 1;
736 break;
737 case OPT_SSHKDF_KEY_CHECK:
738 fips_opts.sshkdf_key_check = 1;
739 break;
740 case OPT_SSKDF_KEY_CHECK:
741 fips_opts.sskdf_key_check = 1;
742 break;
743 case OPT_X963KDF_KEY_CHECK:
744 fips_opts.x963kdf_key_check = 1;
745 break;
746 case OPT_X942KDF_KEY_CHECK:
747 fips_opts.x942kdf_key_check = 1;
748 break;
749 case OPT_NO_PBKDF2_LOWER_BOUND_CHECK:
750 if (!check_non_pedantic_fips(pedantic, "no_pbkdf2_lower_bound_check"))
751 goto end;
752 fips_opts.pbkdf2_lower_bound_check = 0;
753 break;
754 case OPT_ECDH_COFACTOR_CHECK:
755 fips_opts.ecdh_cofactor_check = 1;
756 break;
757 case OPT_QUIET:
758 quiet = 1;
759 /* FALLTHROUGH */
760 case OPT_NO_LOG:
761 self_test_log = 0;
762 break;
763 case OPT_CORRUPT_DESC:
764 self_test_corrupt_desc = opt_arg();
765 break;
766 case OPT_CORRUPT_TYPE:
767 self_test_corrupt_type = opt_arg();
768 break;
769 case OPT_PROV_NAME:
770 prov_name = opt_arg();
771 break;
772 case OPT_MODULE:
773 module_fname = opt_arg();
774 break;
775 case OPT_SECTION_NAME:
776 section_name = opt_arg();
777 break;
778 case OPT_MAC_NAME:
779 mac_name = opt_arg();
780 break;
781 case OPT_CONFIG:
782 parent_config = opt_arg();
783 break;
784 case OPT_MACOPT:
785 if (!sk_OPENSSL_STRING_push(opts, opt_arg()))
786 goto opthelp;
787 if (HAS_PREFIX(opt_arg(), "hexkey:"))
788 gotkey = 1;
789 else if (HAS_PREFIX(opt_arg(), "digest:"))
790 gotdigest = 1;
791 break;
792 case OPT_VERIFY:
793 verify = 1;
794 break;
795 case OPT_SELF_TEST_ONLOAD:
796 set_selftest_onload_option = 1;
797 fips_opts.self_test_onload = 1;
798 break;
799 case OPT_SELF_TEST_ONINSTALL:
800 if (!check_non_pedantic_fips(pedantic, "self_test_oninstall"))
801 goto end;
802 set_selftest_onload_option = 1;
803 fips_opts.self_test_onload = 0;
804 break;
805 }
806 }
807
808 /* No extra arguments. */
809 if (!opt_check_rest_arg(NULL))
810 goto opthelp;
811 if (verify && in_fname == NULL) {
812 BIO_printf(bio_err, "Missing -in option for -verify\n");
813 goto opthelp;
814 }
815
816 if (parent_config != NULL) {
817 /* Test that a parent config can load the module */
818 if (verify_module_load(parent_config)) {
819 ret = OSSL_PROVIDER_available(NULL, prov_name) ? 0 : 1;
820 if (!quiet) {
821 BIO_printf(bio_err, "FIPS provider is %s\n",
822 ret == 0 ? "available" : "not available");
823 }
824 }
825 goto end;
826 }
827 if (module_fname == NULL)
828 goto opthelp;
829
830 tail = opt_path_end(module_fname);
831 if (tail != NULL) {
832 module_path = OPENSSL_strdup(module_fname);
833 if (module_path == NULL)
834 goto end;
835 module_path[tail - module_fname] = '\0';
836 if (!OSSL_PROVIDER_set_default_search_path(NULL, module_path))
837 goto end;
838 }
839
840 if (self_test_log
841 || self_test_corrupt_desc != NULL
842 || self_test_corrupt_type != NULL)
843 OSSL_SELF_TEST_set_callback(NULL, self_test_events, NULL);
844
845 /* Use the default FIPS HMAC digest and key if not specified. */
846 if (!gotdigest && !sk_OPENSSL_STRING_push(opts, "digest:SHA256"))
847 goto end;
848 if (!gotkey && !sk_OPENSSL_STRING_push(opts, "hexkey:" FIPS_KEY_STRING))
849 goto end;
850
851 module_bio = bio_open_default(module_fname, 'r', FORMAT_BINARY);
852 if (module_bio == NULL) {
853 BIO_printf(bio_err, "Failed to open module file\n");
854 goto end;
855 }
856
857 read_buffer = app_malloc(BUFSIZE, "I/O buffer");
858 if (read_buffer == NULL)
859 goto end;
860
861 mac = EVP_MAC_fetch(app_get0_libctx(), mac_name, app_get0_propq());
862 if (mac == NULL) {
863 BIO_printf(bio_err, "Unable to get MAC of type %s\n", mac_name);
864 goto end;
865 }
866
867 ctx = EVP_MAC_CTX_new(mac);
868 if (ctx == NULL) {
869 BIO_printf(bio_err, "Unable to create MAC CTX for module check\n");
870 goto end;
871 }
872
873 if (opts != NULL) {
874 int ok = 1;
875 OSSL_PARAM *params = app_params_new_from_opts(opts, EVP_MAC_settable_ctx_params(mac));
876
877 if (params == NULL)
878 goto end;
879
880 if (!EVP_MAC_CTX_set_params(ctx, params)) {
881 BIO_printf(bio_err, "MAC parameter error\n");
882 ERR_print_errors(bio_err);
883 ok = 0;
884 }
885 app_params_free(params);
886 if (!ok)
887 goto end;
888 }
889
890 ctx2 = EVP_MAC_CTX_dup(ctx);
891 if (ctx2 == NULL) {
892 BIO_printf(bio_err, "Unable to create MAC CTX for install indicator\n");
893 goto end;
894 }
895
896 if (!do_mac(ctx, read_buffer, module_bio, module_mac, &module_mac_len))
897 goto end;
898
899 /* Calculate the MAC for the indicator status - it may not be used */
900 mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL,
901 strlen(INSTALL_STATUS_VAL));
902 if (mem_bio == NULL) {
903 BIO_printf(bio_err, "Unable to create memory BIO\n");
904 goto end;
905 }
906 if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len))
907 goto end;
908
909 if (verify) {
910 if (fips_opts.self_test_onload == 1)
911 install_mac_len = 0;
912 if (!verify_config(in_fname, section_name, module_mac, module_mac_len,
913 install_mac, install_mac_len))
914 goto end;
915 if (!quiet)
916 BIO_printf(bio_err, "VERIFY PASSED\n");
917 } else {
918 conf = generate_config_and_load(prov_name, section_name, module_mac,
919 module_mac_len, &fips_opts);
920 if (conf == NULL)
921 goto end;
922 if (!load_fips_prov_and_run_self_test(prov_name, &is_fips_140_2_prov))
923 goto end;
924
925 /*
926 * In OpenSSL 3.1 the code was changed so that the status indicator is
927 * not written out by default since this is a FIPS 140-3 requirement.
928 * For backwards compatibility - if the detected FIPS provider is 3.0.X
929 * (Which was a FIPS 140-2 validation), then the indicator status will
930 * be written to the config file unless 'self_test_onload' is set on the
931 * command line.
932 */
933 if (set_selftest_onload_option == 0 && is_fips_140_2_prov)
934 fips_opts.self_test_onload = 0;
935
936 fout = out_fname == NULL ? dup_bio_out(FORMAT_TEXT)
937 : bio_open_default(out_fname, 'w', FORMAT_TEXT);
938 if (fout == NULL) {
939 BIO_printf(bio_err, "Failed to open file\n");
940 goto end;
941 }
942
943 if (!write_config_fips_section(fout, section_name,
944 module_mac, module_mac_len, &fips_opts,
945 install_mac, install_mac_len))
946 goto end;
947 if (!quiet)
948 BIO_printf(bio_err, "INSTALL PASSED\n");
949 }
950
951 ret = 0;
952 end:
953 if (ret == 1) {
954 if (!quiet)
955 BIO_printf(bio_err, "%s FAILED\n", verify ? "VERIFY" : "INSTALL");
956 ERR_print_errors(bio_err);
957 }
958
959 cleanup:
960 OPENSSL_free(module_path);
961 BIO_free(fout);
962 BIO_free(mem_bio);
963 BIO_free(module_bio);
964 sk_OPENSSL_STRING_free(opts);
965 EVP_MAC_free(mac);
966 EVP_MAC_CTX_free(ctx2);
967 EVP_MAC_CTX_free(ctx);
968 OPENSSL_free(read_buffer);
969 free_config_and_unload(conf);
970 return ret;
971 }
972
self_test_events(const OSSL_PARAM params[],void * arg)973 static int self_test_events(const OSSL_PARAM params[], void *arg)
974 {
975 const OSSL_PARAM *p = NULL;
976 const char *phase = NULL, *type = NULL, *desc = NULL;
977 int ret = 0;
978
979 p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE);
980 if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
981 goto err;
982 phase = (const char *)p->data;
983
984 p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_DESC);
985 if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
986 goto err;
987 desc = (const char *)p->data;
988
989 p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE);
990 if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
991 goto err;
992 type = (const char *)p->data;
993
994 if (self_test_log) {
995 if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0)
996 BIO_printf(bio_err, "%s : (%s) : ", desc, type);
997 else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0
998 || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0)
999 BIO_printf(bio_err, "%s\n", phase);
1000 }
1001 /*
1002 * The self test code will internally corrupt the KAT test result if an
1003 * error is returned during the corrupt phase.
1004 */
1005 if (strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0
1006 && (self_test_corrupt_desc != NULL
1007 || self_test_corrupt_type != NULL)) {
1008 if (self_test_corrupt_desc != NULL
1009 && strcmp(self_test_corrupt_desc, desc) != 0)
1010 goto end;
1011 if (self_test_corrupt_type != NULL
1012 && strcmp(self_test_corrupt_type, type) != 0)
1013 goto end;
1014 BIO_printf(bio_err, "%s ", phase);
1015 goto err;
1016 }
1017 end:
1018 ret = 1;
1019 err:
1020 return ret;
1021 }
1022