File libgcrypt-fips_run_selftest_at_constructor.patch of Package libgcrypt.2574
Index: libgcrypt-1.6.1/src/global.c
===================================================================
--- libgcrypt-1.6.1.orig/src/global.c 2015-04-21 17:40:23.784433223 +0200
+++ libgcrypt-1.6.1/src/global.c 2015-04-27 18:13:25.310922681 +0200
@@ -124,6 +124,9 @@ global_init (void)
err = _gcry_mpi_init ();
if (err)
goto fail;
+ err = _gcry_fips_run_selftests (0);
+ if (err)
+ goto fail;
return;
Index: libgcrypt-1.6.1/src/fips.c
===================================================================
--- libgcrypt-1.6.1.orig/src/fips.c 2015-04-21 17:40:23.806433562 +0200
+++ libgcrypt-1.6.1/src/fips.c 2015-04-27 18:25:01.617583930 +0200
@@ -607,6 +607,39 @@ get_library_path(const char *symbolname,
return rv;
}
+static gpg_error_t
+get_hmac_path(char **fname)
+{
+ char libpath[4096];
+ gpg_error_t err;
+
+ if (get_library_path ("gcry_check_version", libpath, sizeof(libpath)))
+ err = gpg_error_from_syserror ();
+ else
+ {
+ *fname = _gcry_malloc (strlen (libpath) + 1 + 5 + 1 );
+ if (!*fname)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ char *p;
+
+ /* Prefix the basename with a dot. */
+ strcpy (*fname, libpath);
+ p = strrchr (*fname, '/');
+ if (p)
+ p++;
+ else
+ p = *fname;
+ memmove (p+1, p, strlen (p)+1);
+ *p = '.';
+ strcat (*fname, ".hmac");
+ err = 0;
+ }
+ }
+ return err;
+}
+
/* Run an integrity check on the binary. Returns 0 on success. */
static int
check_binary_integrity (void)
@@ -631,25 +664,9 @@ check_binary_integrity (void)
err = gpg_error (GPG_ERR_INTERNAL);
else
{
- fname = _gcry_malloc (strlen (libpath) + 1 + 5 + 1 );
- if (!fname)
- err = gpg_error_from_syserror ();
- else
- {
- FILE *fp;
- char *p;
-
- /* Prefix the basename with a dot. */
- strcpy (fname, libpath);
- p = strrchr (fname, '/');
- if (p)
- p++;
- else
- p = fname;
- memmove (p+1, p, strlen (p)+1);
- *p = '.';
- strcat (fname, ".hmac");
-
+ FILE *fp;
+ err = get_hmac_path(&fname);
+ if (!err) {
/* Open the file. */
fp = fopen (fname, "r");
if (!fp)
@@ -696,6 +713,33 @@ check_binary_integrity (void)
#endif
}
+int
+can_skip_selftests(void)
+{
+ char *fname = NULL;
+ int ret = 0;
+
+ if (fips_mode())
+ return 0;
+
+ if (get_hmac_path(&fname))
+ return 0;
+
+ /* check the hmac presence */
+ if (access(fname, F_OK))
+ /* no hmac file is present, don't run the tests */
+ if (errno == ENOENT)
+ ret = 1;
+ /* otherwise one of these events happened:
+ access() returned 0
+ -> run the tests
+ some error other than ENOENT occurred
+ -> run the tests anyway and let them fail
+ */
+
+ xfree(fname);
+ return ret;
+}
/* Run the self-tests. If EXTENDED is true, extended versions of the
selftest are run, that is more tests than required by FIPS. */
@@ -705,6 +749,9 @@ _gcry_fips_run_selftests (int extended)
enum module_states result = STATE_ERROR;
gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
+ if (can_skip_selftests())
+ return 0;
+
if (fips_mode ())
fips_new_state (STATE_SELFTEST);