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