VirtualBox

source: vbox/trunk/src/libs/openssl-3.4.1/apps/fipsinstall.c@ 109302

Last change on this file since 109302 was 109052, checked in by vboxsync, 4 weeks ago

openssl-3.4.1: Applied our changes, regenerated files, added missing files and functions. This time with a three way merge. ​bugref:10890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.3 KB
Line 
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
28static OSSL_CALLBACK self_test_events;
29static char *self_test_corrupt_desc = NULL;
30static char *self_test_corrupt_type = NULL;
31static int self_test_log = 1;
32static int quiet = 0;
33
34typedef 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
68const 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
154typedef 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 */
188static 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 */
222static 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
255static 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
264static 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 }
279end:
280 if (!EVP_MAC_final(ctx, out, out_len, outsz))
281 goto err;
282 ret = 1;
283err:
284 return ret;
285}
286
287static int load_fips_prov_and_run_self_test(const char *prov_name)
288{
289 int ret = 0;
290 OSSL_PROVIDER *prov = NULL;
291 OSSL_PARAM params[4], *p = params;
292 char *name = "", *vers = "", *build = "";
293
294 prov = OSSL_PROVIDER_load(NULL, prov_name);
295 if (prov == NULL) {
296 BIO_printf(bio_err, "Failed to load FIPS module\n");
297 goto end;
298 }
299 if (!quiet) {
300 *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME,
301 &name, sizeof(name));
302 *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
303 &vers, sizeof(vers));
304 *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO,
305 &build, sizeof(build));
306 *p = OSSL_PARAM_construct_end();
307 if (!OSSL_PROVIDER_get_params(prov, params)) {
308 BIO_printf(bio_err, "Failed to query FIPS module parameters\n");
309 goto end;
310 }
311 if (OSSL_PARAM_modified(params))
312 BIO_printf(bio_err, "\t%-10s\t%s\n", "name:", name);
313 if (OSSL_PARAM_modified(params + 1))
314 BIO_printf(bio_err, "\t%-10s\t%s\n", "version:", vers);
315 if (OSSL_PARAM_modified(params + 2))
316 BIO_printf(bio_err, "\t%-10s\t%s\n", "build:", build);
317 }
318 ret = 1;
319end:
320 OSSL_PROVIDER_unload(prov);
321 return ret;
322}
323
324static int print_mac(BIO *bio, const char *label, const unsigned char *mac,
325 size_t len)
326{
327 int ret;
328 char *hexstr = NULL;
329
330 hexstr = OPENSSL_buf2hexstr(mac, (long)len);
331 if (hexstr == NULL)
332 return 0;
333 ret = BIO_printf(bio, "%s = %s\n", label, hexstr);
334 OPENSSL_free(hexstr);
335 return ret;
336}
337
338static int write_config_header(BIO *out, const char *prov_name,
339 const char *section)
340{
341 return BIO_printf(out, "openssl_conf = openssl_init\n\n")
342 && BIO_printf(out, "[openssl_init]\n")
343 && BIO_printf(out, "providers = provider_section\n\n")
344 && BIO_printf(out, "[provider_section]\n")
345 && BIO_printf(out, "%s = %s\n\n", prov_name, section);
346}
347
348/*
349 * Outputs a fips related config file that contains entries for the fips
350 * module checksum, installation indicator checksum and the options
351 * conditional_errors and security_checks.
352 *
353 * Returns 1 if the config file is written otherwise it returns 0 on error.
354 */
355static int write_config_fips_section(BIO *out, const char *section,
356 unsigned char *module_mac,
357 size_t module_mac_len,
358 const FIPS_OPTS *opts,
359 unsigned char *install_mac,
360 size_t install_mac_len)
361{
362 int ret = 0;
363
364 if (BIO_printf(out, "[%s]\n", section) <= 0
365 || BIO_printf(out, "activate = 1\n") <= 0
366 || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
367 VERSION_VAL) <= 0
368 || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS,
369 opts->conditional_errors ? "1" : "0") <= 0
370 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SECURITY_CHECKS,
371 opts->security_checks ? "1" : "0") <= 0
372 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HMAC_KEY_CHECK,
373 opts->hmac_key_check ? "1": "0") <= 0
374 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_KMAC_KEY_CHECK,
375 opts->kmac_key_check ? "1": "0") <= 0
376 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK,
377 opts->tls_prf_ems_check ? "1" : "0") <= 0
378 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_NO_SHORT_MAC,
379 opts->no_short_mac ? "1" : "0") <= 0
380 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST,
381 opts->drgb_no_trunc_dgst ? "1" : "0") <= 0
382 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SIGNATURE_DIGEST_CHECK,
383 opts->signature_digest_check ? "1" : "0") <= 0
384 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HKDF_DIGEST_CHECK,
385 opts->hkdf_digest_check ? "1": "0") <= 0
386 || BIO_printf(out, "%s = %s\n",
387 OSSL_PROV_PARAM_TLS13_KDF_DIGEST_CHECK,
388 opts->tls13_kdf_digest_check ? "1": "0") <= 0
389 || BIO_printf(out, "%s = %s\n",
390 OSSL_PROV_PARAM_TLS1_PRF_DIGEST_CHECK,
391 opts->tls1_prf_digest_check ? "1": "0") <= 0
392 || BIO_printf(out, "%s = %s\n",
393 OSSL_PROV_PARAM_SSHKDF_DIGEST_CHECK,
394 opts->sshkdf_digest_check ? "1": "0") <= 0
395 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSKDF_DIGEST_CHECK,
396 opts->sskdf_digest_check ? "1": "0") <= 0
397 || BIO_printf(out, "%s = %s\n",
398 OSSL_PROV_PARAM_X963KDF_DIGEST_CHECK,
399 opts->x963kdf_digest_check ? "1": "0") <= 0
400 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_DSA_SIGN_DISABLED,
401 opts->dsa_sign_disabled ? "1" : "0") <= 0
402 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED,
403 opts->tdes_encrypt_disabled ? "1" : "0") <= 0
404 || BIO_printf(out, "%s = %s\n",
405 OSSL_PROV_PARAM_RSA_PKCS15_PAD_DISABLED,
406 opts->rsa_pkcs15_padding_disabled ? "1" : "0") <= 0
407 || BIO_printf(out, "%s = %s\n",
408 OSSL_PROV_PARAM_RSA_PSS_SALTLEN_CHECK,
409 opts->rsa_pss_saltlen_check ? "1" : "0") <= 0
410 || BIO_printf(out, "%s = %s\n",
411 OSSL_PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED,
412 opts->sign_x931_padding_disabled ? "1" : "0") <= 0
413 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HKDF_KEY_CHECK,
414 opts->hkdf_key_check ? "1": "0") <= 0
415 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_KBKDF_KEY_CHECK,
416 opts->kbkdf_key_check ? "1": "0") <= 0
417 || BIO_printf(out, "%s = %s\n",
418 OSSL_PROV_PARAM_TLS13_KDF_KEY_CHECK,
419 opts->tls13_kdf_key_check ? "1": "0") <= 0
420 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TLS1_PRF_KEY_CHECK,
421 opts->tls1_prf_key_check ? "1": "0") <= 0
422 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSHKDF_KEY_CHECK,
423 opts->sshkdf_key_check ? "1": "0") <= 0
424 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSKDF_KEY_CHECK,
425 opts->sskdf_key_check ? "1": "0") <= 0
426 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_X963KDF_KEY_CHECK,
427 opts->x963kdf_key_check ? "1": "0") <= 0
428 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_X942KDF_KEY_CHECK,
429 opts->x942kdf_key_check ? "1": "0") <= 0
430 || BIO_printf(out, "%s = %s\n",
431 OSSL_PROV_PARAM_PBKDF2_LOWER_BOUND_CHECK,
432 opts->pbkdf2_lower_bound_check ? "1" : "0") <= 0
433 || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_ECDH_COFACTOR_CHECK,
434 opts->ecdh_cofactor_check ? "1": "0") <= 0
435 || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
436 module_mac_len))
437 goto end;
438
439 if (install_mac != NULL && install_mac_len > 0) {
440 if (!print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac,
441 install_mac_len)
442 || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_STATUS,
443 INSTALL_STATUS_VAL) <= 0)
444 goto end;
445 }
446 ret = 1;
447end:
448 return ret;
449}
450
451static CONF *generate_config_and_load(const char *prov_name,
452 const char *section,
453 unsigned char *module_mac,
454 size_t module_mac_len,
455 const FIPS_OPTS *opts)
456{
457 BIO *mem_bio = NULL;
458 CONF *conf = NULL;
459
460 mem_bio = BIO_new(BIO_s_mem());
461 if (mem_bio == NULL)
462 return 0;
463 if (!write_config_header(mem_bio, prov_name, section)
464 || !write_config_fips_section(mem_bio, section,
465 module_mac, module_mac_len,
466 opts, NULL, 0))
467 goto end;
468
469 conf = app_load_config_bio(mem_bio, NULL);
470 if (conf == NULL)
471 goto end;
472
473 if (CONF_modules_load(conf, NULL, 0) <= 0)
474 goto end;
475 BIO_free(mem_bio);
476 return conf;
477end:
478 NCONF_free(conf);
479 BIO_free(mem_bio);
480 return NULL;
481}
482
483static void free_config_and_unload(CONF *conf)
484{
485 if (conf != NULL) {
486 NCONF_free(conf);
487 CONF_modules_unload(1);
488 }
489}
490
491static int verify_module_load(const char *parent_config_file)
492{
493 return OSSL_LIB_CTX_load_config(NULL, parent_config_file);
494}
495
496/*
497 * Returns 1 if the config file entries match the passed in module_mac and
498 * install_mac values, otherwise it returns 0.
499 */
500static int verify_config(const char *infile, const char *section,
501 unsigned char *module_mac, size_t module_mac_len,
502 unsigned char *install_mac, size_t install_mac_len)
503{
504 int ret = 0;
505 char *s = NULL;
506 unsigned char *buf1 = NULL, *buf2 = NULL;
507 long len;
508 CONF *conf = NULL;
509
510 /* read in the existing values and check they match the saved values */
511 conf = app_load_config(infile);
512 if (conf == NULL)
513 goto end;
514
515 s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_VERSION);
516 if (s == NULL || strcmp(s, VERSION_VAL) != 0) {
517 BIO_printf(bio_err, "version not found\n");
518 goto end;
519 }
520 s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_MODULE_MAC);
521 if (s == NULL) {
522 BIO_printf(bio_err, "Module integrity MAC not found\n");
523 goto end;
524 }
525 buf1 = OPENSSL_hexstr2buf(s, &len);
526 if (buf1 == NULL
527 || (size_t)len != module_mac_len
528 || memcmp(module_mac, buf1, module_mac_len) != 0) {
529 BIO_printf(bio_err, "Module integrity mismatch\n");
530 goto end;
531 }
532 if (install_mac != NULL && install_mac_len > 0) {
533 s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_STATUS);
534 if (s == NULL || strcmp(s, INSTALL_STATUS_VAL) != 0) {
535 BIO_printf(bio_err, "install status not found\n");
536 goto end;
537 }
538 s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_MAC);
539 if (s == NULL) {
540 BIO_printf(bio_err, "Install indicator MAC not found\n");
541 goto end;
542 }
543 buf2 = OPENSSL_hexstr2buf(s, &len);
544 if (buf2 == NULL
545 || (size_t)len != install_mac_len
546 || memcmp(install_mac, buf2, install_mac_len) != 0) {
547 BIO_printf(bio_err, "Install indicator status mismatch\n");
548 goto end;
549 }
550 }
551 ret = 1;
552end:
553 OPENSSL_free(buf1);
554 OPENSSL_free(buf2);
555 NCONF_free(conf);
556 return ret;
557}
558
559int fipsinstall_main(int argc, char **argv)
560{
561 int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, pedantic = 0;
562 const char *section_name = "fips_sect";
563 const char *mac_name = "HMAC";
564 const char *prov_name = "fips";
565 BIO *module_bio = NULL, *mem_bio = NULL, *fout = NULL;
566 char *in_fname = NULL, *out_fname = NULL, *prog;
567 char *module_fname = NULL, *parent_config = NULL, *module_path = NULL;
568 const char *tail;
569 EVP_MAC_CTX *ctx = NULL, *ctx2 = NULL;
570 STACK_OF(OPENSSL_STRING) *opts = NULL;
571 OPTION_CHOICE o;
572 unsigned char *read_buffer = NULL;
573 unsigned char module_mac[EVP_MAX_MD_SIZE];
574 size_t module_mac_len = EVP_MAX_MD_SIZE;
575 unsigned char install_mac[EVP_MAX_MD_SIZE];
576 size_t install_mac_len = EVP_MAX_MD_SIZE;
577 EVP_MAC *mac = NULL;
578 CONF *conf = NULL;
579
580 if ((opts = sk_OPENSSL_STRING_new_null()) == NULL)
581 goto end;
582
583 prog = opt_init(argc, argv, fipsinstall_options);
584 while ((o = opt_next()) != OPT_EOF) {
585 switch (o) {
586 case OPT_EOF:
587 case OPT_ERR:
588 opthelp:
589 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
590 goto cleanup;
591 case OPT_HELP:
592 opt_help(fipsinstall_options);
593 ret = 0;
594 goto end;
595 case OPT_IN:
596 in_fname = opt_arg();
597 break;
598 case OPT_OUT:
599 out_fname = opt_arg();
600 break;
601 case OPT_PEDANTIC:
602 fips_opts = pedantic_opts;
603 pedantic = 1;
604 break;
605 case OPT_NO_CONDITIONAL_ERRORS:
606 if (!check_non_pedantic_fips(pedantic, "no_conditional_errors"))
607 goto end;
608 fips_opts.conditional_errors = 0;
609 break;
610 case OPT_NO_SECURITY_CHECKS:
611 if (!check_non_pedantic_fips(pedantic, "no_security_checks"))
612 goto end;
613 fips_opts.security_checks = 0;
614 break;
615 case OPT_HMAC_KEY_CHECK:
616 fips_opts.hmac_key_check = 1;
617 break;
618 case OPT_KMAC_KEY_CHECK:
619 fips_opts.kmac_key_check = 1;
620 break;
621 case OPT_TLS_PRF_EMS_CHECK:
622 fips_opts.tls_prf_ems_check = 1;
623 break;
624 case OPT_NO_SHORT_MAC:
625 fips_opts.no_short_mac = 1;
626 break;
627 case OPT_DISALLOW_DRGB_TRUNC_DIGEST:
628 fips_opts.drgb_no_trunc_dgst = 1;
629 break;
630 case OPT_SIGNATURE_DIGEST_CHECK:
631 fips_opts.signature_digest_check = 1;
632 break;
633 case OPT_HKDF_DIGEST_CHECK:
634 fips_opts.hkdf_digest_check = 1;
635 break;
636 case OPT_TLS13_KDF_DIGEST_CHECK:
637 fips_opts.tls13_kdf_digest_check = 1;
638 break;
639 case OPT_TLS1_PRF_DIGEST_CHECK:
640 fips_opts.tls1_prf_digest_check = 1;
641 break;
642 case OPT_SSHKDF_DIGEST_CHECK:
643 fips_opts.sshkdf_digest_check = 1;
644 break;
645 case OPT_SSKDF_DIGEST_CHECK:
646 fips_opts.sskdf_digest_check = 1;
647 break;
648 case OPT_X963KDF_DIGEST_CHECK:
649 fips_opts.x963kdf_digest_check = 1;
650 break;
651 case OPT_DISALLOW_DSA_SIGN:
652 fips_opts.dsa_sign_disabled = 1;
653 break;
654 case OPT_DISALLOW_TDES_ENCRYPT:
655 fips_opts.tdes_encrypt_disabled = 1;
656 break;
657 case OPT_RSA_PSS_SALTLEN_CHECK:
658 fips_opts.rsa_pss_saltlen_check = 1;
659 break;
660 case OPT_DISALLOW_SIGNATURE_X931_PADDING:
661 fips_opts.sign_x931_padding_disabled = 1;
662 break;
663 case OPT_DISALLOW_PKCS15_PADDING:
664 fips_opts.rsa_pkcs15_padding_disabled = 1;
665 break;
666 case OPT_HKDF_KEY_CHECK:
667 fips_opts.hkdf_key_check = 1;
668 break;
669 case OPT_KBKDF_KEY_CHECK:
670 fips_opts.kbkdf_key_check = 1;
671 break;
672 case OPT_TLS13_KDF_KEY_CHECK:
673 fips_opts.tls13_kdf_key_check = 1;
674 break;
675 case OPT_TLS1_PRF_KEY_CHECK:
676 fips_opts.tls1_prf_key_check = 1;
677 break;
678 case OPT_SSHKDF_KEY_CHECK:
679 fips_opts.sshkdf_key_check = 1;
680 break;
681 case OPT_SSKDF_KEY_CHECK:
682 fips_opts.sskdf_key_check = 1;
683 break;
684 case OPT_X963KDF_KEY_CHECK:
685 fips_opts.x963kdf_key_check = 1;
686 break;
687 case OPT_X942KDF_KEY_CHECK:
688 fips_opts.x942kdf_key_check = 1;
689 break;
690 case OPT_NO_PBKDF2_LOWER_BOUND_CHECK:
691 if (!check_non_pedantic_fips(pedantic, "no_pbkdf2_lower_bound_check"))
692 goto end;
693 fips_opts.pbkdf2_lower_bound_check = 0;
694 break;
695 case OPT_ECDH_COFACTOR_CHECK:
696 fips_opts.ecdh_cofactor_check = 1;
697 break;
698 case OPT_QUIET:
699 quiet = 1;
700 /* FALLTHROUGH */
701 case OPT_NO_LOG:
702 self_test_log = 0;
703 break;
704 case OPT_CORRUPT_DESC:
705 self_test_corrupt_desc = opt_arg();
706 break;
707 case OPT_CORRUPT_TYPE:
708 self_test_corrupt_type = opt_arg();
709 break;
710 case OPT_PROV_NAME:
711 prov_name = opt_arg();
712 break;
713 case OPT_MODULE:
714 module_fname = opt_arg();
715 break;
716 case OPT_SECTION_NAME:
717 section_name = opt_arg();
718 break;
719 case OPT_MAC_NAME:
720 mac_name = opt_arg();
721 break;
722 case OPT_CONFIG:
723 parent_config = opt_arg();
724 break;
725 case OPT_MACOPT:
726 if (!sk_OPENSSL_STRING_push(opts, opt_arg()))
727 goto opthelp;
728 if (HAS_PREFIX(opt_arg(), "hexkey:"))
729 gotkey = 1;
730 else if (HAS_PREFIX(opt_arg(), "digest:"))
731 gotdigest = 1;
732 break;
733 case OPT_VERIFY:
734 verify = 1;
735 break;
736 case OPT_SELF_TEST_ONLOAD:
737 fips_opts.self_test_onload = 1;
738 break;
739 case OPT_SELF_TEST_ONINSTALL:
740 if (!check_non_pedantic_fips(pedantic, "self_test_oninstall"))
741 goto end;
742 fips_opts.self_test_onload = 0;
743 break;
744 }
745 }
746
747 /* No extra arguments. */
748 if (!opt_check_rest_arg(NULL))
749 goto opthelp;
750 if (verify && in_fname == NULL) {
751 BIO_printf(bio_err, "Missing -in option for -verify\n");
752 goto opthelp;
753 }
754
755 if (parent_config != NULL) {
756 /* Test that a parent config can load the module */
757 if (verify_module_load(parent_config)) {
758 ret = OSSL_PROVIDER_available(NULL, prov_name) ? 0 : 1;
759 if (!quiet) {
760 BIO_printf(bio_err, "FIPS provider is %s\n",
761 ret == 0 ? "available" : "not available");
762 }
763 }
764 goto end;
765 }
766 if (module_fname == NULL)
767 goto opthelp;
768
769 tail = opt_path_end(module_fname);
770 if (tail != NULL) {
771 module_path = OPENSSL_strdup(module_fname);
772 if (module_path == NULL)
773 goto end;
774 module_path[tail - module_fname] = '\0';
775 if (!OSSL_PROVIDER_set_default_search_path(NULL, module_path))
776 goto end;
777 }
778
779 if (self_test_log
780 || self_test_corrupt_desc != NULL
781 || self_test_corrupt_type != NULL)
782 OSSL_SELF_TEST_set_callback(NULL, self_test_events, NULL);
783
784 /* Use the default FIPS HMAC digest and key if not specified. */
785 if (!gotdigest && !sk_OPENSSL_STRING_push(opts, "digest:SHA256"))
786 goto end;
787 if (!gotkey && !sk_OPENSSL_STRING_push(opts, "hexkey:" FIPS_KEY_STRING))
788 goto end;
789
790 module_bio = bio_open_default(module_fname, 'r', FORMAT_BINARY);
791 if (module_bio == NULL) {
792 BIO_printf(bio_err, "Failed to open module file\n");
793 goto end;
794 }
795
796 read_buffer = app_malloc(BUFSIZE, "I/O buffer");
797 if (read_buffer == NULL)
798 goto end;
799
800 mac = EVP_MAC_fetch(app_get0_libctx(), mac_name, app_get0_propq());
801 if (mac == NULL) {
802 BIO_printf(bio_err, "Unable to get MAC of type %s\n", mac_name);
803 goto end;
804 }
805
806 ctx = EVP_MAC_CTX_new(mac);
807 if (ctx == NULL) {
808 BIO_printf(bio_err, "Unable to create MAC CTX for module check\n");
809 goto end;
810 }
811
812 if (opts != NULL) {
813 int ok = 1;
814 OSSL_PARAM *params =
815 app_params_new_from_opts(opts, EVP_MAC_settable_ctx_params(mac));
816
817 if (params == NULL)
818 goto end;
819
820 if (!EVP_MAC_CTX_set_params(ctx, params)) {
821 BIO_printf(bio_err, "MAC parameter error\n");
822 ERR_print_errors(bio_err);
823 ok = 0;
824 }
825 app_params_free(params);
826 if (!ok)
827 goto end;
828 }
829
830 ctx2 = EVP_MAC_CTX_dup(ctx);
831 if (ctx2 == NULL) {
832 BIO_printf(bio_err, "Unable to create MAC CTX for install indicator\n");
833 goto end;
834 }
835
836 if (!do_mac(ctx, read_buffer, module_bio, module_mac, &module_mac_len))
837 goto end;
838
839 if (fips_opts.self_test_onload == 0) {
840 mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL,
841 strlen(INSTALL_STATUS_VAL));
842 if (mem_bio == NULL) {
843 BIO_printf(bio_err, "Unable to create memory BIO\n");
844 goto end;
845 }
846 if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len))
847 goto end;
848 } else {
849 install_mac_len = 0;
850 }
851
852 if (verify) {
853 if (!verify_config(in_fname, section_name, module_mac, module_mac_len,
854 install_mac, install_mac_len))
855 goto end;
856 if (!quiet)
857 BIO_printf(bio_err, "VERIFY PASSED\n");
858 } else {
859
860 conf = generate_config_and_load(prov_name, section_name, module_mac,
861 module_mac_len, &fips_opts);
862 if (conf == NULL)
863 goto end;
864 if (!load_fips_prov_and_run_self_test(prov_name))
865 goto end;
866
867 fout =
868 out_fname == NULL ? dup_bio_out(FORMAT_TEXT)
869 : bio_open_default(out_fname, 'w', FORMAT_TEXT);
870 if (fout == NULL) {
871 BIO_printf(bio_err, "Failed to open file\n");
872 goto end;
873 }
874 if (!write_config_fips_section(fout, section_name,
875 module_mac, module_mac_len, &fips_opts,
876 install_mac, install_mac_len))
877 goto end;
878 if (!quiet)
879 BIO_printf(bio_err, "INSTALL PASSED\n");
880 }
881
882 ret = 0;
883end:
884 if (ret == 1) {
885 if (!quiet)
886 BIO_printf(bio_err, "%s FAILED\n", verify ? "VERIFY" : "INSTALL");
887 ERR_print_errors(bio_err);
888 }
889
890cleanup:
891 OPENSSL_free(module_path);
892 BIO_free(fout);
893 BIO_free(mem_bio);
894 BIO_free(module_bio);
895 sk_OPENSSL_STRING_free(opts);
896 EVP_MAC_free(mac);
897 EVP_MAC_CTX_free(ctx2);
898 EVP_MAC_CTX_free(ctx);
899 OPENSSL_free(read_buffer);
900 free_config_and_unload(conf);
901 return ret;
902}
903
904static int self_test_events(const OSSL_PARAM params[], void *arg)
905{
906 const OSSL_PARAM *p = NULL;
907 const char *phase = NULL, *type = NULL, *desc = NULL;
908 int ret = 0;
909
910 p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE);
911 if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
912 goto err;
913 phase = (const char *)p->data;
914
915 p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_DESC);
916 if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
917 goto err;
918 desc = (const char *)p->data;
919
920 p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE);
921 if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
922 goto err;
923 type = (const char *)p->data;
924
925 if (self_test_log) {
926 if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0)
927 BIO_printf(bio_err, "%s : (%s) : ", desc, type);
928 else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0
929 || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0)
930 BIO_printf(bio_err, "%s\n", phase);
931 }
932 /*
933 * The self test code will internally corrupt the KAT test result if an
934 * error is returned during the corrupt phase.
935 */
936 if (strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0
937 && (self_test_corrupt_desc != NULL
938 || self_test_corrupt_type != NULL)) {
939 if (self_test_corrupt_desc != NULL
940 && strcmp(self_test_corrupt_desc, desc) != 0)
941 goto end;
942 if (self_test_corrupt_type != NULL
943 && strcmp(self_test_corrupt_type, type) != 0)
944 goto end;
945 BIO_printf(bio_err, "%s ", phase);
946 goto err;
947 }
948end:
949 ret = 1;
950err:
951 return ret;
952}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette