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


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/ --
                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
                        *: All the include files necessary.
                        Just put the 'include' directory in
                        $INCLUDE or -I, and in your source
                        #include <openssl/file.h>.
                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.
                        openssl.pc: Description of the package
                                configuration parameters.  (Notably,
                                it does NOT mention the library's
                                FIPS build status.)
                certs/: Contains certificates you trust or have issued.
                man/: man pages (add this to your manpath)
                        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
                        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

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

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.

Reply via email to