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