000025719 - How to run the full FIPS 140-2 self tests

Document created by RSA Customer Support Employee on Jun 16, 2016Last modified by RSA Customer Support Employee on Apr 21, 2017
Version 2Show Document
  • View in full screen mode

Article Content

Article Number000025719
Applies ToBSAFE/Micro Edition Suite 3.0.0.1
IssueRun the full FIPS 140-2 self tests
R_FIPS140_self_tests_full() with R_FIPS140_TEST_EXECUTE returns an error R_ERROR_NOT_AVAILABLE. mes_30_security_policy.pdf says on page 10 that you can not use selftest APIs in User Role. So, you need to be Crypto Officer to perform selftest.
CauseBecause MES is often used for SSL communications, the default FIPS mode for MES is the special FIPS_SSL mode (R_FIPS140_MODE_FIPS140_SSL).  To run the full self-test, however, the library must be in normal FIPS mode (R_FIPS140_MODE_FIPS140), which does not allow the MD5 algorithm needed for SSL handshakes.  The library must also be in officer mode (R_FIPS140_ROLE_OFFICER).
Resolution

This sample shows how to set the library into FIPS mode and officer mode so that the full self tests can be run.  It then puts the library back into FIPS_SSL mode, so that MES can be used for SSL communications:

/* $Id: r_fips140_role.c,v 1.3 2008/03/04 01:16:55 sparki Exp $ */
/*
 * Copyright (C) 1998-2005 RSA Security Inc. All rights reserved.
 *
 * This file is intended to demonstrate how to interface to an
 * RSA Security licensed development product. You have a royalty-free
 * right to use, modify, reproduce and distribute this
 * demonstration file (including any modified fips140). This
 * software is provided "as is" without warranties or
 * representations of any kind. RSA Security disclaims all
 * conditions and warranties, statutory and otherwise, both
 * express and implied, with respect to the software, its quality
 * and performance, including but not limited to, all implied
 * warranties of merchantability, fitness for a particular
 * purpose, title and noninfringement of third party rights.
 * Without limiting the foregoing, RSA Security does not warrant
 * that the software is error-free or that errors in the product
 * will be corrected. You agree that RSA Security shall not be
 * liable for any direct, indirect, incidental, special,
 * consequential, punitive or other damages whatsoever resulting
 * from your use of this software or any modified fips140.
 *
 */

/**
 * @file
 * This sample demonstrates how the role and mode of the FIPS140
 * shared library can be changed to run the full self-tests and
 * then changed to another role and mode in order to allow
 * subsequent cryptographic operations to be performed.
 */

#include "r_prod.h"
#include "librarian.h"

static int print_self_test_result(int result);

BIO *bio_out = NULL;
BIO *bio_err = NULL;

/*
 * Main sample program entry point
 *
 * @param argc  [In]  The number of arguments typed on the command line.
 * @param argv  [In]  The array of individual arguments from the command line.
 *
 * @returns  R_ERROR_NONE indicates success.
 *           See @link R_ERROR_IDS Error Identifiers @endlink for valid values.
 */
int main(int argc, char **argv)
{
    int ret = R_ERROR_FAILED;
    R_LIB_CTX *lib_ctx = NULL;
    R_FIPS140 *fips140 = R_FIPS140_get_default();
    int failure_reason = 0;
    const char *failure_reason_string = NULL;
    R_FIPS140_MODE mode;
    R_FIPS140_ROLE role;
    R_FIPS140_TEST test;

    /*************************************************************************
     * Step 1. Create BIO to stderr
     * BIOs are the Basic Input/Output mechanism provided by RSA and are
     * recommended for all input and output from applications.
     *************************************************************************/
    if ((bio_out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
    {
        ret = R_ERROR_ALLOC_FAILURE;
        goto end;
    }

    if ((bio_err = BIO_new_fp(stderr, BIO_NOCLOSE)) == NULL)
    {
        ret = R_ERROR_ALLOC_FAILURE;
        goto end;
    }

    /*************************************************************************
     * Step 2. Create the library context.
     * Retrieve the default resource list and create a library context to
     * provide access to all configurable aspects of the library.
     *************************************************************************/
    if ((ret = PRODUCT_LIBRARY_NEW(PRODUCT_DEFAULT_RESOURCE_LIST(),
        R_RES_FLAG_DEF, &lib_ctx)) != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Unable to create library context\n");
        goto end;
    }

    /*************************************************************************
     * Step 3. The default role for the FIPS140 shared library is USER. In
     * order for the FIPS140 Full Self Tests to be run it is necessary to
     * change the role to OFFICER.
     *************************************************************************/
     if ((ret = R_FIPS140_set_role(fips140,
        R_FIPS140_ROLE_OFFICER)) != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Setting officer role failed\n");
        goto end;
    }

    /* Check that we are in officer role */
    if ((ret = R_FIPS140_get_role(fips140, &role))
        != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Getting role failed\n");
        goto end;
    }

    if (role != R_FIPS140_ROLE_OFFICER)
    {
        BIO_printf(bio_err, "Setting officer role failed\n");
        ret = R_ERROR_FAILED;
        goto end;
    }

    /*************************************************************************
     * Step 4. The default mode for the FIPS140 shared library is FIPS140 SSL.
     * In order for the FIPS140 Full Self Tests to be run it is necessary to
     * change the mode to FIPS140.
     *************************************************************************/
    if ((ret = R_FIPS140_set_mode(fips140, R_FIPS140_MODE_FIPS140))
        != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Setting FIPS140 SSL mode failed\n");
        goto end;
    }

    /* Check that we are in FIPS140 mode */
    if ((ret = R_FIPS140_get_mode(fips140, &mode))
        != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Getting mode failed\n");
        goto end;
    }

    if (mode != R_FIPS140_MODE_FIPS140)
    {
        BIO_printf(bio_err, "Setting FIPS140 mode failed\n");
        ret = R_ERROR_FAILED;
        goto end;
    }

    /*************************************************************************
     * Step 5. Load the FIPS140 module into memory, intitialise and run the
     * full test suite.
     *************************************************************************/
    ret = R_FIPS140_load_module(fips140);
    if (ret != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Unable to load FIPS module\n");
        goto end;
    }


    ret = R_FIPS140_library_init(fips140, lib_ctx);
    if (ret != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Failed to initialize FIPS library\n");
        goto end;
    }

    BIO_printf(bio_out, "\nRunning in the officer role.\n");
   
    BIO_printf(bio_out, "\nRun Full Self Test:\n");
    test = R_FIPS140_TEST_EXECUTE;
    ret = R_FIPS140_set_info(fips140, R_FIPS140_INFO_ID_SELF_TESTS_FULL,
        &test);
    if ((ret = print_self_test_result(ret)) != R_ERROR_NONE)
    {
        goto end;
    }
 
    /*************************************************************************
     * Step 5. Unload fips module so it can be reloaded after changing role.
     *************************************************************************/
    ret = R_FIPS140_unload_module(fips140);
    if (ret != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Unable to unload FIPS module\n");
        goto end;
    }

    /*************************************************************************
     * Step 6. Change role from OFFICER to USER in order to run an application.
     *************************************************************************/
    BIO_printf(bio_err, "\nSetting user role\n");
    if ((ret = R_FIPS140_set_role(fips140,
        R_FIPS140_ROLE_USER)) != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Setting user role failed\n");
        goto end;
    }

    if ((ret = R_FIPS140_get_role(fips140, &role))
        != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Getting role failed\n");
        goto end;
    }

    if (role != R_FIPS140_ROLE_USER)
    {
        BIO_printf(bio_err, "Setting user role failed\n");
        ret = R_ERROR_FAILED;
        goto end;
    }

    BIO_printf(bio_err, "Setting user role succeeded\n");

    /*************************************************************************
     * Step 7. Change mode from FIPS140 to FIPS140 SSL in order to run an
     * application.
     *************************************************************************/
    BIO_printf(bio_err, "\nSetting FIPS140 SSL mode\n");
    if ((ret = R_FIPS140_set_mode(fips140, R_FIPS140_MODE_FIPS140_SSL))
        != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Setting FIPS140 SSL mode failed\n");
        goto end;
    }

    /* Check that we are in FIPS140 SSL mode */
    if ((ret = R_FIPS140_get_mode(fips140, &mode))
        != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Getting mode failed\n");
        goto end;
    }

    if (mode != R_FIPS140_MODE_FIPS140_SSL)
    {
        BIO_printf(bio_err, "Setting FIPS140 SSL mode failed\n");
        ret = R_ERROR_FAILED;
        goto end;
    }
 
    BIO_printf(bio_err, "Setting FIPS140 SSL mode succeeded\n");

    /*************************************************************************
     * Step 8. Re-init library (reloads module).
     *************************************************************************/
    if ((ret = R_FIPS140_library_init(fips140, lib_ctx)) != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Re-init with USER, FIPS140 SSL object failed\n");
        goto end;
    }

    /**************************************************************************
     * With the role now set to USER and mode set to FIPS140 SSL,
     * cryptographic operations can now be performed.
     *************************************************************************/

end:

    /* If the shared library failed to load, find out why. */
    if (ret == R_ERROR_MODULE_LOAD_FAILED)
    {
        BIO_printf(bio_err, "FIPS140 shared library load failure\n");

        /* Get the failure reason code */
        if (R_FIPS140_get_failure_reason(fips140, &failure_reason) ==
            R_ERROR_NONE)
        {
            BIO_printf(bio_err, "  Reason: %d", failure_reason);
        }

        /* Additionally, get the failure reason string */
        if (R_FIPS140_get_failure_reason_string(fips140, &failure_reason_string)
            == R_ERROR_NONE)
        {
            BIO_printf(bio_err, " (%s)", failure_reason_string);
        }

        BIO_printf(bio_err, "\n");
    }

    /*************************************************************************
     * Destroy the dynamically allocated objects and return an exit code.
     *************************************************************************/
    if (bio_out != NULL)
    {
        BIO_free(bio_out);
    }

    if (bio_err != NULL)
    {
        BIO_free(bio_err);
    }

    if (lib_ctx != NULL)
    {
        PRODUCT_LIBRARY_FREE(lib_ctx);
    }

    return(R_ERROR_EXIT_CODE(ret));
}


/*
 * Displays the self test results
 */
static int print_self_test_result(int result)
{
    int ret = result;

    if (result == R_ERROR_NONE)
    {
        BIO_printf(bio_out, "SELF TEST: Passed\n");
        goto end;
    }

    if (result == R_ERROR_DENIED)
    {
        BIO_printf(bio_out, "SELF TEST: Failed - Not in Officer Role\n");
        goto end;
    }

    if (result == R_ERROR_NOT_AVAILABLE)
    {
        BIO_printf(bio_out, "SELF TEST: Failed - Not in NIST Mode\n");
        goto end;
    }

    BIO_printf(bio_out, "SELF TEST: Failed with Error Code %d\n", result);

end:

    return(ret);
}

Legacy Article IDa39458

Attachments

    Outcomes