xref: /freebsd/crypto/openssl/doc/man7/fips_module.pod (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1=pod
2
3=head1 NAME
4
5fips_module - OpenSSL fips module guide
6
7=head1 SYNOPSIS
8
9See the individual manual pages for details.
10
11=head1 DESCRIPTION
12
13This guide details different ways that OpenSSL can be used in conjunction
14with the FIPS module. Which is the correct approach to use will depend on your
15own specific circumstances and what you are attempting to achieve.
16
17For information related to installing the FIPS module see
18L<https://github.com/openssl/openssl/blob/master/README-FIPS.md>.
19
20Note that the old functions FIPS_mode() and FIPS_mode_set() are no longer
21present so you must remove them from your application if you use them.
22
23Applications written to use the OpenSSL 3.0 FIPS module should not use any
24legacy APIs or features that avoid the FIPS module. Specifically this includes:
25
26=over 4
27
28=item *
29
30Low level cryptographic APIs (use the high level APIs, such as EVP, instead)
31
32=item *
33
34Engines
35
36=item *
37
38Any functions that create or modify custom "METHODS" (for example
39EVP_MD_meth_new(), EVP_CIPHER_meth_new(), EVP_PKEY_meth_new(), RSA_meth_new(),
40EC_KEY_METHOD_new(), etc.)
41
42=back
43
44All of the above APIs are deprecated in OpenSSL 3.0 - so a simple rule is to
45avoid using all deprecated functions. See L<migration_guide(7)> for a list of
46deprecated functions.
47
48=head2 Making all applications use the FIPS module by default
49
50One simple approach is to cause all applications that are using OpenSSL to only
51use the FIPS module for cryptographic algorithms by default.
52
53This approach can be done purely via configuration. As long as applications are
54built and linked against OpenSSL 3.0 and do not override the loading of the
55default config file or its settings then they can automatically start using the
56FIPS module without the need for any further code changes.
57
58To do this the default OpenSSL config file will have to be modified. The
59location of this config file will depend on the platform, and any options that
60were given during the build process. You can check the location of the config
61file by running this command:
62
63    $ openssl version -d
64    OPENSSLDIR: "/usr/local/ssl"
65
66Caution: Many Operating Systems install OpenSSL by default. It is a common error
67to not have the correct version of OpenSSL in your $PATH. Check that you are
68running an OpenSSL 3.0 version like this:
69
70    $ openssl version -v
71    OpenSSL 3.0.0-dev xx XXX xxxx (Library: OpenSSL 3.0.0-dev xx XXX xxxx)
72
73The B<OPENSSLDIR> value above gives the directory name for where the default
74config file is stored. So in this case the default config file will be called
75F</usr/local/ssl/openssl.cnf>.
76
77Edit the config file to add the following lines near the beginning:
78
79    config_diagnostics = 1
80    openssl_conf = openssl_init
81
82    .include /usr/local/ssl/fipsmodule.cnf
83
84    [openssl_init]
85    providers = provider_sect
86
87    [provider_sect]
88    fips = fips_sect
89    base = base_sect
90
91    [base_sect]
92    activate = 1
93
94Obviously the include file location above should match the path and name of the
95FIPS module config file that you installed earlier.
96See L<https://github.com/openssl/openssl/blob/master/README-FIPS.md>.
97
98For FIPS usage, it is recommended that the B<config_diagnostics> option is
99enabled to prevent accidental use of non-FIPS validated algorithms via broken
100or mistaken configuration.  See L<config(5)>.
101
102Any applications that use OpenSSL 3.0 and are started after these changes are
103made will start using only the FIPS module unless those applications take
104explicit steps to avoid this default behaviour. Note that this configuration
105also activates the "base" provider. The base provider does not include any
106cryptographic algorithms (and therefore does not impact the validation status of
107any cryptographic operations), but does include other supporting algorithms that
108may be required. It is designed to be used in conjunction with the FIPS module.
109
110This approach has the primary advantage that it is simple, and no code changes
111are required in applications in order to benefit from the FIPS module. There are
112some disadvantages to this approach:
113
114=over 4
115
116=item *
117
118You may not want all applications to use the FIPS module.
119
120It may be the case that some applications should and some should not use the
121FIPS module.
122
123=item *
124
125If applications take explicit steps to not load the default config file or
126set different settings.
127
128This method will not work for these cases.
129
130=item *
131
132The algorithms available in the FIPS module are a subset of the algorithms
133that are available in the default OpenSSL Provider.
134
135If any applications attempt to use any algorithms that are not present,
136then they will fail.
137
138=item *
139
140Usage of certain deprecated APIs avoids the use of the FIPS module.
141
142If any applications use those APIs then the FIPS module will not be used.
143
144=back
145
146=head2 Selectively making applications use the FIPS module by default
147
148A variation on the above approach is to do the same thing on an individual
149application basis. The default OpenSSL config file depends on the compiled in
150value for B<OPENSSLDIR> as described in the section above. However it is also
151possible to override the config file to be used via the B<OPENSSL_CONF>
152environment variable. For example the following, on Unix, will cause the
153application to be executed with a non-standard config file location:
154
155    $ OPENSSL_CONF=/my/nondefault/openssl.cnf myapplication
156
157Using this mechanism you can control which config file is loaded (and hence
158whether the FIPS module is loaded) on an application by application basis.
159
160This removes the disadvantage listed above that you may not want all
161applications to use the FIPS module. All the other advantages and disadvantages
162still apply.
163
164=head2 Programmatically loading the FIPS module (default library context)
165
166Applications may choose to load the FIPS provider explicitly rather than relying
167on config to do this. The config file is still necessary in order to hold the
168FIPS module config data (such as its self test status and integrity data). But
169in this case we do not automatically activate the FIPS provider via that config
170file.
171
172To do things this way configure as per
173L</Making all applications use the FIPS module by default> above, but edit the
174F<fipsmodule.cnf> file to remove or comment out the line which says
175C<activate = 1> (note that setting this value to 0 is I<not> sufficient).
176This means all the required config information will be available to load the
177FIPS module, but it is not automatically loaded when the application starts. The
178FIPS provider can then be loaded programmatically like this:
179
180    #include <openssl/provider.h>
181
182    int main(void)
183    {
184        OSSL_PROVIDER *fips;
185        OSSL_PROVIDER *base;
186
187        fips = OSSL_PROVIDER_load(NULL, "fips");
188        if (fips == NULL) {
189            printf("Failed to load FIPS provider\n");
190            exit(EXIT_FAILURE);
191        }
192        base = OSSL_PROVIDER_load(NULL, "base");
193        if (base == NULL) {
194            OSSL_PROVIDER_unload(fips);
195            printf("Failed to load base provider\n");
196            exit(EXIT_FAILURE);
197        }
198
199        /* Rest of application */
200
201        OSSL_PROVIDER_unload(base);
202        OSSL_PROVIDER_unload(fips);
203        exit(EXIT_SUCCESS);
204    }
205
206Note that this should be one of the first things that you do in your
207application. If any OpenSSL functions get called that require the use of
208cryptographic functions before this occurs then, if no provider has yet been
209loaded, then the default provider will be automatically loaded. If you then
210later explicitly load the FIPS provider then you will have both the FIPS and the
211default provider loaded at the same time. It is undefined which implementation
212of an algorithm will be used if multiple implementations are available and you
213have not explicitly specified via a property query (see below) which one should
214be used.
215
216Also note that in this example we have additionally loaded the "base" provider.
217This loads a sub-set of algorithms that are also available in the default
218provider - specifically non cryptographic ones which may be used in conjunction
219with the FIPS provider. For example this contains algorithms for encoding and
220decoding keys. If you decide not to load the default provider then you
221will usually want to load the base provider instead.
222
223In this example we are using the "default" library context. OpenSSL functions
224operate within the scope of a library context. If no library context is
225explicitly specified then the default library context is used. For further
226details about library contexts see the L<OSSL_LIB_CTX(3)> man page.
227
228=head2 Loading the FIPS module at the same time as other providers
229
230It is possible to have the FIPS provider and other providers (such as the
231default provider) all loaded at the same time into the same library context. You
232can use a property query string during algorithm fetches to specify which
233implementation you would like to use.
234
235For example to fetch an implementation of SHA256 which conforms to FIPS
236standards you can specify the property query C<fips=yes> like this:
237
238    EVP_MD *sha256;
239
240    sha256 = EVP_MD_fetch(NULL, "SHA2-256", "fips=yes");
241
242If no property query is specified, or more than one implementation matches the
243property query then it is undefined which implementation of a particular
244algorithm will be returned.
245
246This example shows an explicit request for an implementation of SHA256 from the
247default provider:
248
249    EVP_MD *sha256;
250
251    sha256 = EVP_MD_fetch(NULL, "SHA2-256", "provider=default");
252
253It is also possible to set a default property query string. The following
254example sets the default property query of C<fips=yes> for all fetches within
255the default library context:
256
257    EVP_set_default_properties(NULL, "fips=yes");
258
259If a fetch function has both an explicit property query specified, and a
260default property query is defined then the two queries are merged together and
261both apply. The local property query overrides the default properties if the
262same property name is specified in both.
263
264There are two important built-in properties that you should be aware of:
265
266The "provider" property enables you to specify which provider you want an
267implementation to be fetched from, e.g. C<provider=default> or C<provider=fips>.
268All algorithms implemented in a provider have this property set on them.
269
270There is also the C<fips> property. All FIPS algorithms match against the
271property query C<fips=yes>. There are also some non-cryptographic algorithms
272available in the default and base providers that also have the C<fips=yes>
273property defined for them. These are the encoder and decoder algorithms that
274can (for example) be used to write out a key generated in the FIPS provider to a
275file. The encoder and decoder algorithms are not in the FIPS module itself but
276are allowed to be used in conjunction with the FIPS algorithms.
277
278It is possible to specify default properties within a config file. For example
279the following config file automatically loads the default and FIPS providers and
280sets the default property value to be C<fips=yes>. Note that this config file
281does not load the "base" provider. All supporting algorithms that are in "base"
282are also in "default", so it is unnecessary in this case:
283
284    config_diagnostics = 1
285    openssl_conf = openssl_init
286
287    .include /usr/local/ssl/fipsmodule.cnf
288
289    [openssl_init]
290    providers = provider_sect
291    alg_section = algorithm_sect
292
293    [provider_sect]
294    fips = fips_sect
295    default = default_sect
296
297    [default_sect]
298    activate = 1
299
300    [algorithm_sect]
301    default_properties = fips=yes
302
303=head2 Programmatically loading the FIPS module (nondefault library context)
304
305In addition to using properties to separate usage of the FIPS module from other
306usages this can also be achieved using library contexts. In this example we
307create two library contexts. In one we assume the existence of a config file
308called F<openssl-fips.cnf> that automatically loads and configures the FIPS and
309base providers. The other library context will just use the default provider.
310
311    OSSL_LIB_CTX *fips_libctx, *nonfips_libctx;
312    OSSL_PROVIDER *defctxnull = NULL;
313    EVP_MD *fipssha256 = NULL, *nonfipssha256 = NULL;
314    int ret = 1;
315
316    /*
317     * Create two nondefault library contexts. One for fips usage and
318     * one for non-fips usage
319     */
320    fips_libctx = OSSL_LIB_CTX_new();
321    nonfips_libctx = OSSL_LIB_CTX_new();
322    if (fips_libctx == NULL || nonfips_libctx == NULL)
323        goto err;
324
325    /* Prevent anything from using the default library context */
326    defctxnull = OSSL_PROVIDER_load(NULL, "null");
327
328    /*
329     * Load config file for the FIPS library context. We assume that
330     * this config file will automatically activate the FIPS and base
331     * providers so we don't need to explicitly load them here.
332     */
333    if (!OSSL_LIB_CTX_load_config(fips_libctx, "openssl-fips.cnf"))
334        goto err;
335
336    /*
337     * We don't need to do anything special to load the default
338     * provider into nonfips_libctx. This happens automatically if no
339     * other providers are loaded.
340     * Because we don't call OSSL_LIB_CTX_load_config() explicitly for
341     * nonfips_libctx it will just use the default config file.
342     */
343
344    /* As an example get some digests */
345
346    /* Get a FIPS validated digest */
347    fipssha256 = EVP_MD_fetch(fips_libctx, "SHA2-256", NULL);
348    if (fipssha256 == NULL)
349        goto err;
350
351    /* Get a non-FIPS validated digest */
352    nonfipssha256 = EVP_MD_fetch(nonfips_libctx, "SHA2-256", NULL);
353    if (nonfipssha256 == NULL)
354        goto err;
355
356    /* Use the digests */
357
358    printf("Success\n");
359    ret = 0;
360
361    err:
362    EVP_MD_free(fipssha256);
363    EVP_MD_free(nonfipssha256);
364    OSSL_LIB_CTX_free(fips_libctx);
365    OSSL_LIB_CTX_free(nonfips_libctx);
366    OSSL_PROVIDER_unload(defctxnull);
367
368    return ret;
369
370Note that we have made use of the special "null" provider here which we load
371into the default library context. We could have chosen to use the default
372library context for FIPS usage, and just create one additional library context
373for other usages - or vice versa. However if code has not been converted to use
374library contexts then the default library context will be automatically used.
375This could be the case for your own existing applications as well as certain
376parts of OpenSSL itself. Not all parts of OpenSSL are library context aware. If
377this happens then you could "accidentally" use the wrong library context for a
378particular operation. To be sure this doesn't happen you can load the "null"
379provider into the default library context. Because a provider has been
380explicitly loaded, the default provider will not automatically load. This means
381code using the default context by accident will fail because no algorithms will
382be available.
383
384See L<migration_guide(7)/Library Context> for additional information about the
385Library Context.
386
387=head2 Using Encoders and Decoders with the FIPS module
388
389Encoders and decoders are used to read and write keys or parameters from or to
390some external format (for example a PEM file). If your application generates
391keys or parameters that then need to be written into PEM or DER format
392then it is likely that you will need to use an encoder to do this. Similarly
393you need a decoder to read previously saved keys and parameters. In most cases
394this will be invisible to you if you are using APIs that existed in
395OpenSSL 1.1.1 or earlier such as L<i2d_PrivateKey(3)>. However the appropriate
396encoder/decoder will need to be available in the library context associated with
397the key or parameter object. The built-in OpenSSL encoders and decoders are
398implemented in both the default and base providers and are not in the FIPS
399module boundary. However since they are not cryptographic algorithms themselves
400it is still possible to use them in conjunction with the FIPS module, and
401therefore these encoders/decoders have the C<fips=yes> property against them.
402You should ensure that either the default or base provider is loaded into the
403library context in this case.
404
405=head2 Using the FIPS module in SSL/TLS
406
407Writing an application that uses libssl in conjunction with the FIPS module is
408much the same as writing a normal libssl application. If you are using global
409properties and the default library context to specify usage of FIPS validated
410algorithms then this will happen automatically for all cryptographic algorithms
411in libssl. If you are using a nondefault library context to load the FIPS
412provider then you can supply this to libssl using the function
413L<SSL_CTX_new_ex(3)>. This works as a drop in replacement for the function
414L<SSL_CTX_new(3)> except it provides you with the capability to specify the
415library context to be used. You can also use the same function to specify
416libssl specific properties to use.
417
418In this first example we create two SSL_CTX objects using two different library
419contexts.
420
421    /*
422     * We assume that a nondefault library context with the FIPS
423     * provider loaded has been created called fips_libctx.
424     */
425    SSL_CTX *fips_ssl_ctx = SSL_CTX_new_ex(fips_libctx, NULL, TLS_method());
426    /*
427     * We assume that a nondefault library context with the default
428     * provider loaded has been created called non_fips_libctx.
429     */
430    SSL_CTX *non_fips_ssl_ctx = SSL_CTX_new_ex(non_fips_libctx, NULL,
431                                               TLS_method());
432
433In this second example we create two SSL_CTX objects using different properties
434to specify FIPS usage:
435
436    /*
437     * The "fips=yes" property includes all FIPS approved algorithms
438     * as well as encoders from the default provider that are allowed
439     * to be used. The NULL below indicates that we are using the
440     * default library context.
441     */
442    SSL_CTX *fips_ssl_ctx = SSL_CTX_new_ex(NULL, "fips=yes", TLS_method());
443    /*
444     * The "provider!=fips" property allows algorithms from any
445     * provider except the FIPS provider
446     */
447    SSL_CTX *non_fips_ssl_ctx = SSL_CTX_new_ex(NULL, "provider!=fips",
448                                               TLS_method());
449
450=head2 Confirming that an algorithm is being provided by the FIPS module
451
452A chain of links needs to be followed to go from an algorithm instance to the
453provider that implements it. The process is similar for all algorithms. Here the
454example of a digest is used.
455
456To go from an B<EVP_MD_CTX> to an B<EVP_MD>, use L<EVP_MD_CTX_md(3)> .
457To go from the B<EVP_MD> to its B<OSSL_PROVIDER>,
458use L<EVP_MD_get0_provider(3)>.
459To extract the name from the B<OSSL_PROVIDER>, use
460L<OSSL_PROVIDER_get0_name(3)>.
461
462=head1 NOTES
463
464Some released versions of OpenSSL do not include a validated
465FIPS provider.  To determine which versions have undergone
466the validation process, please refer to the
467L<OpenSSL Downloads page|https://www.openssl.org/source/>.  If you
468require FIPS-approved functionality, it is essential to build your FIPS
469provider using one of the validated versions listed there.  Normally,
470it is possible to utilize a FIPS provider constructed from one of the
471validated versions alongside F<libcrypto> and F<libssl> compiled from any
472release within the same major release series.  This flexibility enables
473you to address bug fixes and CVEs that fall outside the FIPS boundary.
474
475=head1 SEE ALSO
476
477L<migration_guide(7)>, L<crypto(7)>, L<fips_config(5)>,
478L<https://www.openssl.org/source/>
479
480=head1 HISTORY
481
482The FIPS module guide was created for use with the new FIPS provider
483in OpenSSL 3.0.
484
485=head1 COPYRIGHT
486
487Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
488
489Licensed under the Apache License 2.0 (the "License").  You may not use
490this file except in compliance with the License.  You can obtain a copy
491in the file LICENSE in the source distribution or at
492L<https://www.openssl.org/source/license.html>.
493
494=cut
495