Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/apps/fipsinstall.c
34870 views
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
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
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
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
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
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
*/
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
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
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
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
*/
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
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
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
979