copensslfips

FIPS_mode_set() code not found in openssl package


I am new to openssl, and I downloaded openssl-fips-2.0.1 codes from openssl, however, I was not able to trace to the definition of FIPS_mode_set() as stated in the documentation and security policy. I did find, however, fips_set_mode() in fips.c, but they are not referring to the same, am I right?

Where is the definition? Please advise me.


Solution

  • FIPS_mode_set() code not found in openssl package

    You have to know how to ask...

    openssl-1.0.1f$ grep -R FIPS_mode_set *
    apps/openssl.c:     if (!FIPS_mode_set(1)) {
    CHANGES:  *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying
    crypto/cpt_err.c:{ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"},
    crypto/evp/evp_cnf.c:   if (!FIPS_mode() && !FIPS_mode_set(1))
    crypto/crypto.h:int FIPS_mode_set(int r);
    crypto/o_fips.c:int FIPS_mode_set(int r)
    Binary file fips_premain_dso matches
    ssl/ssltest.c:      if(!FIPS_mode_set(1))
    util/libeay.num:FIPS_mode_set    3253    EXIST::FUNCTION:
    openssl-1.0.1f$ 
    

    The declaration is in crypto/crypto.h and the definition is in crypto/o_fips.c. Here's from o_fips.c:

    int FIPS_mode_set(int r)
        {
        OPENSSL_init();
    #ifdef OPENSSL_FIPS
    #ifndef FIPS_AUTH_USER_PASS
    #define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password"
    #endif
        if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS))
            return 0;
        if (r)
            RAND_set_rand_method(FIPS_rand_get_method());
        else
            RAND_set_rand_method(NULL);
        return 1;
    #else
        if (r == 0)
            return 1;
        CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED);
        return 0;
    #endif
        }
    

    If you were looking for FIPS_mode_set to enter into "FIPS mode" with special setup or switch some algorithms, that does not happen at this step.

    It happens earlier when linking. What happens under the hood is fipsld is you compiler, and it looks for an invocation of LD. If LD is not invoked, then fipsld just calls your regular compiler (probably /usr/bin/gcc). If it sees an invocation of LD, then it does three things.

    First, it compiles fips_premin.c. Then it calls the real ld to perform the final link with all your object file and the fips_premain.o it produced. Finally, it calls incore to swap in the FIPS Object Module, calculate the signature over the relevant text and data (relevant means the FIPS code and data), and then embeds the signature in the executable.

    The signature is generated with an HMAC, and the key is embedded in the executable. There's nothing special about it, and its constant across all executables throughout the world. Here's the key used: etaonrishdlcupfm.


    If you are not taking special steps when build your executable, then you are probably missing some steps. Here are the steps to use fipsld and incore:

    $ export CC=`find /usr/local -name fipsld`
    $ echo $CC 
    /usr/local/ssl/fips-2.0/bin/fipsld
    $ export FIPSLD_CC=`find /usr/bin -name gcc`
    $ echo $FIPSLD_CC 
    /usr/bin/gcc
    

    Now, do a standard config and make. Sometimes you have to do config, then adjust CC and FIPSLD_CC, and then run make because some config files choke on the arrangement. Sometimes you have to open a Makefile after config and change CC to /usr/local/ssl/fips-2.0/bin/fipsld. There's lots of ways to do it in an effort to work around particular packaging.


    I downloaded openssl-fips-2.0.1 codes from openssl, however, I was not able to trace to the definition of FIPS_mode_set()

    openssl-fips-NNN provides the FIPS validated cryptography if you build the FIPS Object Module according to the Security Policy. You can find the OpenSSL FIPS 1402- Security Policy at here.

    If all you did was download and build openssl-fips-NNN, then you are probably not using FIPS validated cryptography. There's a procedure to follow, and that includes getting a "trusted" copy of the source code. You can download and verify a signature, but you need a FIPS validated signature checker, which creates a chicken-and-the-egg problem because you can't build it from sources. So the practical solution is to order the CD from the OpenSSL Foundation. Its bizarre, but its the truth. See, for example, the OpenSSL FIPS User Guide or the OpenSSL FIPS Security Policy, Appendix B, Controlled Distribution File Fingerprint.

    Once you have the FIPS Object Module built and installed, you can build the FIPS Capable version of the library. The FIPS Capable OpenSSL will use the FIPS Object Module, if available. Think of it as a "pluggable" architecture.

    The FIPS Capable version of the library is simply openssl-NNN, such as openssl-1.0.1e and openssl-1.0.1f. Its what you know and love.


    You might also consider something like ctags as a source code browser to help you find things and jump around. See Exuberant Ctags on Sourceforge.