/* * PKCS #11 FIPS Power-Up Self Test. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* $Id: fipstest.c,v 1.31 2012/06/28 17:55:06 rrelyea%redhat.com Exp $ */ #ifndef NSS_FIPS_DISABLED #include "seccomon.h" #include "lgdb.h" #include "blapi.h" /* * different platforms have different ways of calling and initial entry point * when the dll/.so is loaded. Most platforms support either a posix pragma * or the GCC attribute. Some platforms suppor a pre-defined name, and some * platforms have a link line way of invoking this function. */ /* The pragma */ #if defined(USE_INIT_PRAGMA) #pragma init(lg_startup_tests) #endif /* GCC Attribute */ #if defined(__GNUC__) && !defined(NSS_NO_INIT_SUPPORT) #define INIT_FUNCTION __attribute__((constructor)) #else #define INIT_FUNCTION #endif static void INIT_FUNCTION lg_startup_tests(void); /* Windows pre-defined entry */ #if defined(XP_WIN) && !defined(NSS_NO_INIT_SUPPORT) #include BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function LPVOID lpReserved) // reserved { // Perform actions based on the reason for calling. switch (fdwReason) { case DLL_PROCESS_ATTACH: // Initialize once for each new process. // Return FALSE to fail DLL load. lg_startup_tests(); break; case DLL_THREAD_ATTACH: // Do thread-specific initialization. break; case DLL_THREAD_DETACH: // Do thread-specific cleanup. break; case DLL_PROCESS_DETACH: // Perform any necessary cleanup. break; } return TRUE; // Successful DLL_PROCESS_ATTACH. } #endif static PRBool lg_self_tests_ran = PR_FALSE; static PRBool lg_self_tests_success = PR_FALSE; static void lg_local_function(void) { } /* * This function is called at dll load time, the code tha makes this * happen is platform specific on defined above. */ static void lg_startup_tests(void) { const char *libraryName = LG_LIB_NAME; PORT_Assert(!lg_self_tests_ran); PORT_Assert(!lg_self_tests_success); lg_self_tests_ran = PR_TRUE; lg_self_tests_success = PR_FALSE; /* just in case */ /* no self tests required for the legacy db, only the integrity check */ /* check the integrity of our shared library */ if (!BLAPI_SHVerify(libraryName, (PRFuncPtr)&lg_local_function)) { /* something is wrong with the library, fail without enabling * the fips token */ return; } /* FIPS product has been installed and is functioning, allow * the module to operate in fips mode */ lg_self_tests_success = PR_TRUE; } PRBool lg_FIPSEntryOK() { #ifdef NSS_NO_INIT_SUPPORT /* this should only be set on platforms that can't handle one of the INIT * schemes. This code allows those platforms to continue to function, * though they don't meet the strict NIST requirements. If NO_INIT_SUPPORT * is not set, and init support has not been properly enabled, softken * will always fail because of the test below */ if (!lg_self_tests_ran) { lg_startup_tests(); } #endif return lg_self_tests_success; } #endif /* NSS_FIPS_DISABLED */