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