diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | doc/gcrypt.texi | 45 | ||||
-rw-r--r-- | src/fips.c | 2 | ||||
-rw-r--r-- | src/hwfeatures.c | 76 | ||||
-rw-r--r-- | src/mpicalc.c | 36 |
5 files changed, 159 insertions, 2 deletions
@@ -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 ********************************************************** @@ -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; |