/* Basic initialization which is required to initialize mutexes and such. It does not run a full initialization so that the filling of the random pool can be delayed until it is actually needed. We assume that this function is used before any concurrent access happens. */ static void initialize_basics(void) { static int initialized = 0; if (!initialized) { initialized = 1; #ifdef USE_RANDOM_DAEMON _gcry_daemon_initialize_basics (); #endif /*USE_RANDOM_DAEMON*/ /* Make sure that we are still using the values we have traditionally used for the random levels. */ gcry_assert (GCRY_WEAK_RANDOM == 0 && GCRY_STRONG_RANDOM == 1 && GCRY_VERY_STRONG_RANDOM == 2); int err = gpgrt_lock_init(&pool_lock); if (err) log_fatal ("failed to initialize the pool lock: %s\n", gpg_strerror (err)); } }
/* Check whether the OS is in FIPS mode and record that in a module local variable. If FORCE is passed as true, fips mode will be enabled anyway. Note: This function is not thread-safe and should be called before any threads are created. This function may only be called once. */ void _gcry_initialize_fips_mode (int force) { static int done; gpg_error_t err; /* Make sure we are not accidentally called twice. */ if (done) { if ( fips_mode () ) { fips_new_state (STATE_FATALERROR); fips_noreturn (); } /* If not in fips mode an assert is sufficient. */ gcry_assert (!done); } done = 1; /* If the calling application explicitly requested fipsmode, do so. */ if (force) { gcry_assert (!no_fips_mode_required); goto leave; } /* For testing the system it is useful to override the system provided detection of the FIPS mode and force FIPS mode using a file. The filename is hardwired so that there won't be any confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is actually used. The file itself may be empty. */ if ( !access (FIPS_FORCE_FILE, F_OK) ) { gcry_assert (!no_fips_mode_required); goto leave; } /* Checking based on /proc file properties. */ { static const char procfname[] = "/proc/sys/crypto/fips_enabled"; FILE *fp; int saved_errno; fp = fopen (procfname, "r"); if (fp) { char line[256]; if (fgets (line, sizeof line, fp) && atoi (line)) { /* System is in fips mode. */ fclose (fp); gcry_assert (!no_fips_mode_required); goto leave; } fclose (fp); } else if ((saved_errno = errno) != ENOENT && saved_errno != EACCES && !access ("/proc/version", F_OK) ) { /* Problem reading the fips file despite that we have the proc file system. We better stop right away. */ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", procfname, strerror (saved_errno)); #ifdef HAVE_SYSLOG syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " "reading `%s' failed: %s - abort", procfname, strerror (saved_errno)); #endif /*HAVE_SYSLOG*/ abort (); } } /* Fips not not requested, set flag. */ no_fips_mode_required = 1; leave: if (!no_fips_mode_required) { /* Yes, we are in FIPS mode. */ FILE *fp; /* Intitialize the lock to protect the FSM. */ err = gpgrt_lock_init (&fsm_lock); if (err) { /* If that fails we can't do anything but abort the process. We need to use log_info so that the FSM won't get involved. */ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", gpg_strerror (err)); #ifdef HAVE_SYSLOG syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " "creating FSM lock failed: %s - abort", gpg_strerror (err)); #endif /*HAVE_SYSLOG*/ abort (); } /* If the FIPS force files exists, is readable and has a number != 0 on its first line, we enable the enforced fips mode. */ fp = fopen (FIPS_FORCE_FILE, "r"); if (fp) { char line[256]; if (fgets (line, sizeof line, fp) && atoi (line)) enforced_fips_mode = 1; fclose (fp); } /* Now get us into the INIT state. */ fips_new_state (STATE_INIT); } return; }
int main (int argc, char **argv) { int last_argc = -1; int rc; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--help")) { puts ( "usage: ./t-lock [options]\n" "\n" "Options:\n" " --verbose Show what is going on\n" " --debug Flyswatter\n" ); exit (0); } if (!strcmp (*argv, "--verbose")) { verbose = 1; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose = debug = 1; argc--; argv++; } } srand (time(NULL)*getpid()); if (!gpg_error_check_version (GPG_ERROR_VERSION)) { die ("gpg_error_check_version returned an error"); errorcount++; } init_accounts (); check_accounts (); run_test (); check_accounts (); /* Run a second time to check deinit code. */ run_test (); check_accounts (); /* And a third time to test an explicit init. */ rc = gpgrt_lock_init (&accounts_lock); if (rc) fail ("gpgrt_lock_init failed at %d: %s", __LINE__, gpg_strerror (rc)); run_test (); check_accounts (); if (verbose) print_accounts (); return errorcount ? 1 : 0; }