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