LCOV - code coverage report
Current view: top level - src - hwfeatures.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 21 50 42.0 %
Date: 2015-11-05 17:08:00 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /* hwfeatures.c - Detect hardware features.
       2             :  * Copyright (C) 2007, 2011  Free Software Foundation, Inc.
       3             :  * Copyright (C) 2012  g10 Code GmbH
       4             :  *
       5             :  * This file is part of Libgcrypt.
       6             :  *
       7             :  * Libgcrypt is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU Lesser General Public License as
       9             :  * published by the Free Software Foundation; either version 2.1 of
      10             :  * the License, or (at your option) any later version.
      11             :  *
      12             :  * Libgcrypt is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : #include <stdio.h>
      23             : #include <ctype.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <stdarg.h>
      27             : #include <unistd.h>
      28             : #ifdef HAVE_SYSLOG
      29             : # include <syslog.h>
      30             : #endif /*HAVE_SYSLOG*/
      31             : 
      32             : #include "g10lib.h"
      33             : #include "hwf-common.h"
      34             : 
      35             : /* The name of a file used to globally disable selected features. */
      36             : #define HWF_DENY_FILE "/etc/gcrypt/hwf.deny"
      37             : 
      38             : /* A table to map hardware features to a string.  */
      39             : static struct
      40             : {
      41             :   unsigned int flag;
      42             :   const char *desc;
      43             : } hwflist[] =
      44             :   {
      45             :     { HWF_PADLOCK_RNG,     "padlock-rng" },
      46             :     { HWF_PADLOCK_AES,     "padlock-aes" },
      47             :     { HWF_PADLOCK_SHA,     "padlock-sha" },
      48             :     { HWF_PADLOCK_MMUL,    "padlock-mmul"},
      49             :     { HWF_INTEL_CPU,       "intel-cpu" },
      50             :     { HWF_INTEL_FAST_SHLD, "intel-fast-shld" },
      51             :     { HWF_INTEL_BMI2,      "intel-bmi2" },
      52             :     { HWF_INTEL_SSSE3,     "intel-ssse3" },
      53             :     { HWF_INTEL_PCLMUL,    "intel-pclmul" },
      54             :     { HWF_INTEL_AESNI,     "intel-aesni" },
      55             :     { HWF_INTEL_RDRAND,    "intel-rdrand" },
      56             :     { HWF_INTEL_AVX,       "intel-avx" },
      57             :     { HWF_INTEL_AVX2,      "intel-avx2" },
      58             :     { HWF_ARM_NEON,        "arm-neon" }
      59             :   };
      60             : 
      61             : /* A bit vector with the hardware features which shall not be used.
      62             :    This variable must be set prior to any initialization.  */
      63             : static unsigned int disabled_hw_features;
      64             : 
      65             : /* A bit vector describing the hardware features currently
      66             :    available. */
      67             : static unsigned int hw_features;
      68             : 
      69             : /* Convenience macros.  */
      70             : #define my_isascii(c) (!((c) & 0x80))
      71             : 
      72             : 
      73             : 
      74             : /* Disable a feature by name.  This function must be called *before*
      75             :    _gcry_detect_hw_features is called.  */
      76             : gpg_err_code_t
      77           0 : _gcry_disable_hw_feature (const char *name)
      78             : {
      79             :   int i;
      80             : 
      81           0 :   for (i=0; i < DIM (hwflist); i++)
      82           0 :     if (!strcmp (hwflist[i].desc, name))
      83             :       {
      84           0 :         disabled_hw_features |= hwflist[i].flag;
      85           0 :         return 0;
      86             :       }
      87           0 :   return GPG_ERR_INV_NAME;
      88             : }
      89             : 
      90             : 
      91             : /* Return a bit vector describing the available hardware features.
      92             :    The HWF_ constants are used to test for them. */
      93             : unsigned int
      94      105129 : _gcry_get_hw_features (void)
      95             : {
      96      105129 :   return hw_features;
      97             : }
      98             : 
      99             : 
     100             : /* Enumerate all features.  The caller is expected to start with an
     101             :    IDX of 0 and then increment IDX until NULL is returned.  */
     102             : const char *
     103          15 : _gcry_enum_hw_features (int idx, unsigned int *r_feature)
     104             : {
     105          15 :   if (idx < 0 || idx >= DIM (hwflist))
     106           1 :     return NULL;
     107          14 :   if (r_feature)
     108          14 :     *r_feature = hwflist[idx].flag;
     109          14 :   return hwflist[idx].desc;
     110             : }
     111             : 
     112             : 
     113             : /* Read a file with features which shall not be used.  The file is a
     114             :    simple text file where empty lines and lines with the first non
     115             :    white-space character being '#' are ignored.  */
     116             : static void
     117          31 : parse_hwf_deny_file (void)
     118             : {
     119          31 :   const char *fname = HWF_DENY_FILE;
     120             :   FILE *fp;
     121             :   char buffer[256];
     122             :   char *p, *pend;
     123          31 :   int i, lnr = 0;
     124             : 
     125          31 :   fp = fopen (fname, "r");
     126          31 :   if (!fp)
     127          31 :     return;
     128             : 
     129             :   for (;;)
     130             :     {
     131           0 :       if (!fgets (buffer, sizeof buffer, fp))
     132             :         {
     133           0 :           if (!feof (fp))
     134             :             {
     135             : #ifdef HAVE_SYSLOG
     136           0 :               syslog (LOG_USER|LOG_WARNING,
     137             :                       "Libgcrypt warning: error reading '%s', line %d",
     138             :                       fname, lnr);
     139             : #endif /*HAVE_SYSLOG*/
     140             :             }
     141           0 :           fclose (fp);
     142           0 :           return;
     143             :         }
     144           0 :       lnr++;
     145           0 :       for (p=buffer; my_isascii (*p) && isspace (*p); p++)
     146             :         ;
     147           0 :       pend = strchr (p, '\n');
     148           0 :       if (pend)
     149           0 :         *pend = 0;
     150           0 :       pend = p + (*p? (strlen (p)-1):0);
     151           0 :       for ( ;pend > p; pend--)
     152           0 :         if (my_isascii (*pend) && isspace (*pend))
     153           0 :           *pend = 0;
     154           0 :       if (!*p || *p == '#')
     155           0 :         continue;
     156             : 
     157           0 :       for (i=0; i < DIM (hwflist); i++)
     158             :         {
     159           0 :           if (!strcmp (hwflist[i].desc, p))
     160             :             {
     161           0 :               disabled_hw_features |= hwflist[i].flag;
     162           0 :               break;
     163             :             }
     164             :         }
     165           0 :       if (i == DIM (hwflist))
     166             :         {
     167             : #ifdef HAVE_SYSLOG
     168           0 :           syslog (LOG_USER|LOG_WARNING,
     169             :                   "Libgcrypt warning: unknown feature in '%s', line %d",
     170             :                   fname, lnr);
     171             : #endif /*HAVE_SYSLOG*/
     172             :         }
     173           0 :     }
     174             : }
     175             : 
     176             : 
     177             : /* Detect the available hardware features.  This function is called
     178             :    once right at startup and we assume that no other threads are
     179             :    running.  */
     180             : void
     181          31 : _gcry_detect_hw_features (void)
     182             : {
     183          31 :   hw_features = 0;
     184             : 
     185          31 :   if (fips_mode ())
     186          31 :     return; /* Hardware support is not to be evaluated.  */
     187             : 
     188          31 :   parse_hwf_deny_file ();
     189             : 
     190             : #if defined (HAVE_CPU_ARCH_X86)
     191             :   {
     192          31 :     hw_features = _gcry_hwf_detect_x86 ();
     193             :   }
     194             : #endif /* HAVE_CPU_ARCH_X86 */
     195             : #if defined (HAVE_CPU_ARCH_ARM)
     196             :   {
     197             :     hw_features = _gcry_hwf_detect_arm ();
     198             :   }
     199             : #endif /* HAVE_CPU_ARCH_ARM */
     200             : 
     201          31 :   hw_features &= ~disabled_hw_features;
     202             : }

Generated by: LCOV version 1.11