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