summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--doc/gcrypt.texi45
-rw-r--r--src/fips.c2
-rw-r--r--src/hwfeatures.c76
-rw-r--r--src/mpicalc.c36
5 files changed, 159 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 4c95e8a8..978047f9 100644
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,8 @@ Noteworthy changes in version 1.6.0 (unreleased)
* Changed gcry_pk_genkey for "ecc" to only include the curve name and
not the parameters. The flag "param" may be used to revert this.
+ * Added a feature to globally disable selected hardware features.
+
* Interface changes relative to the 1.5.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcry_ac_* REMOVED.
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index 97dac1c8..f3af29fc 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -210,6 +210,7 @@ of the library are verified.
* Initializing the library:: How to initialize the library.
* Multi-Threading:: How Libgcrypt can be used in a MT environment.
* Enabling FIPS mode:: How to enable the FIPS mode.
+* Hardware features:: How to disable hardware features.
@end menu
@@ -609,6 +610,50 @@ switch back to standard mode without terminating the process first.
If the logging verbosity level of Libgcrypt has been set to at least
2, the state transitions and the self-tests are logged.
+@node Hardware features
+@section How to disable hardware features
+@cindex hardware features
+
+Libgcrypt makes use of certain hardware features. If the use of a
+feature is not desired it may be either be disabled by a program or
+globally using a configuration file. The currently supported features
+are
+
+@table @code
+@item padlock-rng
+@item padlock-aes
+@item padlock-sha
+@item padlock-mmul
+@item intel-pclmul
+@item intel-aesni
+@item intel-rdrand
+@item intel-avx
+@item intel-avx2
+@item arm-neon
+@end table
+
+To disable a feature for all processes using Libgcrypt 1.6 or newer,
+create the file @file{/etc/gcrypt/hwf.deny} and put each feature not
+to be used on a single line. Empty lines, white space, and lines
+prefixed with a hash mark are ignored. The file should be world
+readable.
+
+To disable a feature specifically for a program that program must tell
+it Libgcrypt before before calling @code{gcry_check_version}.
+Example:@footnote{NB. Libgcrypt uses the RDRAND feature only as one
+source of entropy. A CPU with a broken RDRAND will thus not
+compromise of the random number generator}
+
+@example
+ gcry_control (GCRYCTL_DISABLE_HWF, "intel-rdrand", NULL);
+@end example
+
+@noindent
+To print the list of active features you may use this command:
+
+@example
+ mpicalc --print-config | grep ^hwflist: | tr : '\n' | tail -n +2
+@end example
@c **********************************************************
diff --git a/src/fips.c b/src/fips.c
index 1d7a6a44..8148dcdb 100644
--- a/src/fips.c
+++ b/src/fips.c
@@ -36,7 +36,7 @@
#include "hmac256.h"
-/* The name of the file used to foce libgcrypt into fips mode. */
+/* The name of the file used to force libgcrypt into fips mode. */
#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
diff --git a/src/hwfeatures.c b/src/hwfeatures.c
index 43847d22..66998167 100644
--- a/src/hwfeatures.c
+++ b/src/hwfeatures.c
@@ -20,14 +20,20 @@
#include <config.h>
#include <stdio.h>
+#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
#include "g10lib.h"
#include "hwf-common.h"
+/* The name of a file used to globally disable selected features. */
+#define HWF_DENY_FILE "/etc/gcrypt/hwf.deny"
/* A table to map hardware features to a string. */
static struct
@@ -56,7 +62,11 @@ static unsigned int disabled_hw_features;
available. */
static unsigned int hw_features;
+/* Convenience macros. */
+#define my_isascii(c) (!((c) & 0x80))
+
+
/* Disable a feature by name. This function must be called *before*
_gcry_detect_hw_features is called. */
gpg_err_code_t
@@ -96,6 +106,70 @@ _gcry_enum_hw_features (int idx, unsigned int *r_feature)
}
+/* Read a file with features which shall not be used. The file is a
+ simple text file where empty lines and lines with the first non
+ white-space character being '#' are ignored. */
+static void
+parse_hwf_deny_file (void)
+{
+ const char *fname = HWF_DENY_FILE;
+ FILE *fp;
+ char buffer[256];
+ char *p, *pend;
+ int i, lnr = 0;
+
+ fp = fopen (fname, "r");
+ if (!fp)
+ return;
+
+ for (;;)
+ {
+ if (!fgets (buffer, sizeof buffer, fp))
+ {
+ if (!feof (fp))
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt warning: error reading '%s', line %d",
+ fname, lnr);
+#endif /*HAVE_SYSLOG*/
+ }
+ fclose (fp);
+ return;
+ }
+ lnr++;
+ for (p=buffer; my_isascii (*p) && isspace (*p); p++)
+ ;
+ pend = strchr (p, '\n');
+ if (pend)
+ *pend = 0;
+ pend = p + (*p? (strlen (p)-1):0);
+ for ( ;pend > p; pend--)
+ if (my_isascii (*pend) && isspace (*pend))
+ *pend = 0;
+ if (!*p || *p == '#')
+ continue;
+
+ for (i=0; i < DIM (hwflist); i++)
+ {
+ if (!strcmp (hwflist[i].desc, p))
+ {
+ disabled_hw_features |= hwflist[i].flag;
+ break;
+ }
+ }
+ if (i == DIM (hwflist))
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt warning: unknown feature in '%s', line %d",
+ fname, lnr);
+#endif /*HAVE_SYSLOG*/
+ }
+ }
+}
+
+
/* Detect the available hardware features. This function is called
once right at startup and we assume that no other threads are
running. */
@@ -107,6 +181,8 @@ _gcry_detect_hw_features (void)
if (fips_mode ())
return; /* Hardware support is not to be evaluated. */
+ parse_hwf_deny_file ();
+
#if defined (HAVE_CPU_ARCH_X86)
{
hw_features = _gcry_hwf_detect_x86 ();
diff --git a/src/mpicalc.c b/src/mpicalc.c
index 335b7c39..b2b43351 100644
--- a/src/mpicalc.c
+++ b/src/mpicalc.c
@@ -40,6 +40,7 @@
#define MPICALC_VERSION "2.0"
+#define NEED_LIBGCRYPT_VERSION "1.6.0"
#define STACKSIZE 500
static gcry_mpi_t stack[STACKSIZE];
@@ -309,6 +310,7 @@ main (int argc, char **argv)
{
const char *pgm;
int last_argc = -1;
+ int print_config = 0;
int i, c;
int state = 0;
char strbuf[1000];
@@ -350,10 +352,28 @@ main (int argc, char **argv)
"Simple interactive big integer RPN calculator\n"
"\n"
"Options:\n"
- " --version print version information\n",
+ " --version print version information\n"
+ " --print-config print the Libgcrypt config\n"
+ " --disable-hwf NAME disable feature NAME\n",
pgm, gcry_check_version (NULL));
exit (0);
}
+ else if (!strcmp (*argv, "--print-config"))
+ {
+ argc--; argv++;
+ print_config = 1;
+ }
+ else if (!strcmp (*argv, "--disable-hwf"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
+ fprintf (stderr, "%s: unknown hardware feature `%s'"
+ " - option ignored\n", pgm, *argv);
+ argc--; argv++;
+ }
+ }
}
if (argc)
@@ -362,6 +382,20 @@ main (int argc, char **argv)
exit (1);
}
+ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
+ {
+ fprintf (stderr, "%s: Libgcrypt is too old (need %s, have %s)\n",
+ pgm, NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
+ exit (1);
+ }
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (print_config)
+ {
+ gcry_control (GCRYCTL_PRINT_CONFIG, stdout);
+ exit (0);
+ }
+
for (i = 0; i < STACKSIZE; i++)
stack[i] = NULL;
stackidx = 0;