Hi, I just figured I'd write something up for your perusal, modification, and possible inclusion into the HOWTO list. I'm attaching it as a file; if it doesn't come through, please let me know, and I'll resend it in a message body.
If there are any glaring inaccuracies I would very much like to know about them, since I wrote this out of my explorations for figuring out how to use the library myself. ;) Thanks! -Kyle H
!DRAFT! -- FIPS-140-2 certification is not yet finalized -- !DRAFT! Using the FIPS-certified mode of OpenSSL There are really three main steps to using the FIPS mode of OpenSSL: 1) Create the library in FIPS-certified mode 2) Call FIPS_mode_set(3) in your application just after initializing the OpenSSL library 3) Link your application against the FIPS-certified OpenSSL library However, as they say, the devil is always in the details. This is one programmer's experience with getting this done. 1) Create the library in FIPS-certified mode ===NOTE: THIS IS A DRAFT DOCUMENT, AND DUPLICATES INFORMATION TO ===BE FOUND IN THE OPENSSL FIPS SECURITY POLICY. IF THERE IS ANY ===DISCREPANCY, THE OPENSSL FIPS SECURITY POLICY IS CORRECT, AND ===THIS DOCUMENT IS WRONG. YOU ARE HEREBY WARNED. This is, really, the toughest part of the procedure. In order to accomplish this, you need version 0.9.7j (or higher in the 0.9.7 series). (If 0.9.7j isn't out by the time you read this, please get the latest 0.9.7 stable snapshot.) To compile it in FIPS-certified mode, the appropriate command to configure it is: ./config fips with no other options that affect what functions go into the library. You ARE allowed to specify -d (for debugging), and --prefix (to specify where it is to be installed); however, if you specify -d, you need to have electric-fence (by Bruce Perens) installed, and you MUST NOT STRIP ANY BINARY YOU CREATE. The explanation for this is described in the Mechanics section of this document. After compiling this (with 'make'), it is advisable to test the compilation (with 'make test'). The test suite used for FIPS mode is much longer than the test suite used for a non-FIPS build, though on a reasonably fast system you won't have time for a coffee break during it. After the tests complete successfully (if they don't, get onto the openssl-users@openssl.org mailing list for assistance -- directions are on the http://openssl.org/ website), type 'make install' and there will be several things installed in $(PREFIX)/openssl/ -- bin/ openssl: The openssl command-line interface c_rehash: A shell script to rehash a CA cert dir fipsld: The tool you need to link your app with the FIPS-certified library include/ openssl/ *: All the include files necessary. Just put the 'include' directory in $INCLUDE or -I, and in your source #include <openssl/file.h>. lib/ fipscanister.o: pre- and post- library segment isolation for in-memory image verification (see Mechanics section) fipscanister.o.sha1: keyed hmac value for fipscanister.o, needed for verification that it hasn't been munged fips_premain.c: Code that must be compiled and linked to run before the main() procedure in your binary image. This verifies that the library hasn't been tampered with. fips_premain.c.sha1: keyed hmac value for fips_premain.c, verified by fipsld during link time. libcrypto.a: FIPS-certified cryptographic library. libssl.a: SSL library. pkgconfig/ openssl.pc: Description of the package configuration parameters. (Notably, it does NOT mention the library's FIPS build status.) ssl/ certs/: Contains certificates you trust or have issued. man/: man pages (add this to your manpath) misc/ CA.pl: perl version of CA script CA.sh: Bourne shell version of CA script c_hash: Prints the simple hashed filename that a given set of X.509 certs would be placed in. Does not check prior hash values. c_info: Prints basic information (filename, subject, issuer, end date) about a set of X.509 certs, without performing any verification. c_issuer: Prints out the individual issuers of a set of X.509 certs. c_name: Prints the subject names of a set of X.509 certs. openssl.cnf: Standard configuration file for OpenSSL library. private/: Contains private keys for your own use. 2) Call FIPS_mode_set(3) in your application after you initialize the OpenSSL library This is a fairly easy thing to do. The FIPS_mode_set(3) function has the following prototype: int FIPS_mode_set(int onoff); To go into FIPS mode, call it with a non-zero parameter. To come out of FIPS mode, call it with a zero parameter. HOWEVER: YOU MUST VERIFY THE RETURN VALUE. If the return value is 0, then FIPS mode initialization failed for some reason, and you may not be able to get any information on why. Regardless, if you attempt to go into FIPS mode, and fail, and then attempt to call any FIPS algorithms, no encryption will be perfomed, and you will get an error. !!TODO!!: explain what the error code they will get is The FIPS_mode_set performs the required verification of the FIPS module in memory, as well as verifying that it operates properly. If it returns 1, all of the self-tests occurred properly (including the self-test of the random number generator), and the self-tests of the various algorithms. If you attempt to call FIPS_mode_set(1); after you have already done so, you will force the module into an error condition, and cause it to fail its selftest. To reset it out of this state, call FIPS_mode_set(0); FIPS_mode_set(1); to cause the selftest to reinitiate. (If this doesn't bring it back into a running state, you should inform the user that an internal FIPS error occurred, and then terminate.) If you attempt to use any non-FIPS-compliant algorithms when in FIPS mode (such as the MD5 hashing algorithm), you will get an error indicating the error was in the FIPS subsystem. When you obtain the error value, it will be FIPS_F_NON_FIPS_METHOD. 3) Link your application against the FIPS library This is the second-most-difficult thing to do, because if you don't know how to do it, you're setting yourself for frustration. The key to it is using the fipsld command, mentioned above in section 1. The fipsld command is actually a shell script, which can (for various reasons) be used in the same way as $(CC). Its prerequisites are: $FIPSLD_CC or $CC must be set to the name of your C compiler. (If you want to use it as a replacement for $(CC) in your makefiles, it will generally make more sense to use $FIPSLD_CC so they don't step on each other.) Its options are: -c: Compile the source file passed to it. (The entire commandline is passed to ${FIPSLD_CC}.) -x: Enable debugging output of the fingerprinting premain procedure. At this point, the method used to enforce that the premain procedure gets called before main() is believed to operate on ALL gcc targets. You may link against either a dynamic or static version of the library, as up to you. There are pros and cons to both, though, and you should consult the relevant literature for your particular need. Author: Kyle A Hamilton Date: 2006 Feb 16 Copyright assigned to the OpenSSL project.