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