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: 2016-11-29 14:56:30 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_SSE4_1,    "intel-sse4.1" },
      54             :     { HWF_INTEL_PCLMUL,    "intel-pclmul" },
      55             :     { HWF_INTEL_AESNI,     "intel-aesni" },
      56             :     { HWF_INTEL_RDRAND,    "intel-rdrand" },
      57             :     { HWF_INTEL_AVX,       "intel-avx" },
      58             :     { HWF_INTEL_AVX2,      "intel-avx2" },
      59             :     { HWF_ARM_NEON,        "arm-neon" },
      60             :     { HWF_ARM_AES,         "arm-aes" },
      61             :     { HWF_ARM_SHA1,        "arm-sha1" },
      62             :     { HWF_ARM_SHA2,        "arm-sha2" },
      63             :     { HWF_ARM_PMULL,       "arm-pmull" }
      64             :   };
      65             : 
      66             : /* A bit vector with the hardware features which shall not be used.
      67             :    This variable must be set prior to any initialization.  */
      68             : static unsigned int disabled_hw_features;
      69             : 
      70             : /* A bit vector describing the hardware features currently
      71             :    available. */
      72             : static unsigned int hw_features;
      73             : 
      74             : /* Convenience macros.  */
      75             : #define my_isascii(c) (!((c) & 0x80))
      76             : 
      77             : 
      78             : 
      79             : /* Disable a feature by name.  This function must be called *before*
      80             :    _gcry_detect_hw_features is called.  */
      81             : gpg_err_code_t
      82           0 : _gcry_disable_hw_feature (const char *name)
      83             : {
      84             :   int i;
      85             : 
      86           0 :   for (i=0; i < DIM (hwflist); i++)
      87           0 :     if (!strcmp (hwflist[i].desc, name))
      88             :       {
      89           0 :         disabled_hw_features |= hwflist[i].flag;
      90           0 :         return 0;
      91             :       }
      92           0 :   return GPG_ERR_INV_NAME;
      93             : }
      94             : 
      95             : 
      96             : /* Return a bit vector describing the available hardware features.
      97             :    The HWF_ constants are used to test for them. */
      98             : unsigned int
      99      341222 : _gcry_get_hw_features (void)
     100             : {
     101      341222 :   return hw_features;
     102             : }
     103             : 
     104             : 
     105             : /* Enumerate all features.  The caller is expected to start with an
     106             :    IDX of 0 and then increment IDX until NULL is returned.  */
     107             : const char *
     108          20 : _gcry_enum_hw_features (int idx, unsigned int *r_feature)
     109             : {
     110          20 :   if (idx < 0 || idx >= DIM (hwflist))
     111           1 :     return NULL;
     112          19 :   if (r_feature)
     113          19 :     *r_feature = hwflist[idx].flag;
     114          19 :   return hwflist[idx].desc;
     115             : }
     116             : 
     117             : 
     118             : /* Read a file with features which shall not be used.  The file is a
     119             :    simple text file where empty lines and lines with the first non
     120             :    white-space character being '#' are ignored.  */
     121             : static void
     122          32 : parse_hwf_deny_file (void)
     123             : {
     124          32 :   const char *fname = HWF_DENY_FILE;
     125             :   FILE *fp;
     126             :   char buffer[256];
     127             :   char *p, *pend;
     128          32 :   int i, lnr = 0;
     129             : 
     130          32 :   fp = fopen (fname, "r");
     131          32 :   if (!fp)
     132          32 :     return;
     133             : 
     134             :   for (;;)
     135             :     {
     136           0 :       if (!fgets (buffer, sizeof buffer, fp))
     137             :         {
     138           0 :           if (!feof (fp))
     139             :             {
     140             : #ifdef HAVE_SYSLOG
     141           0 :               syslog (LOG_USER|LOG_WARNING,
     142             :                       "Libgcrypt warning: error reading '%s', line %d",
     143             :                       fname, lnr);
     144             : #endif /*HAVE_SYSLOG*/
     145             :             }
     146           0 :           fclose (fp);
     147           0 :           return;
     148             :         }
     149           0 :       lnr++;
     150           0 :       for (p=buffer; my_isascii (*p) && isspace (*p); p++)
     151             :         ;
     152           0 :       pend = strchr (p, '\n');
     153           0 :       if (pend)
     154           0 :         *pend = 0;
     155           0 :       pend = p + (*p? (strlen (p)-1):0);
     156           0 :       for ( ;pend > p; pend--)
     157           0 :         if (my_isascii (*pend) && isspace (*pend))
     158           0 :           *pend = 0;
     159           0 :       if (!*p || *p == '#')
     160           0 :         continue;
     161             : 
     162           0 :       for (i=0; i < DIM (hwflist); i++)
     163             :         {
     164           0 :           if (!strcmp (hwflist[i].desc, p))
     165             :             {
     166           0 :               disabled_hw_features |= hwflist[i].flag;
     167           0 :               break;
     168             :             }
     169             :         }
     170           0 :       if (i == DIM (hwflist))
     171             :         {
     172             : #ifdef HAVE_SYSLOG
     173           0 :           syslog (LOG_USER|LOG_WARNING,
     174             :                   "Libgcrypt warning: unknown feature in '%s', line %d",
     175             :                   fname, lnr);
     176             : #endif /*HAVE_SYSLOG*/
     177             :         }
     178           0 :     }
     179             : }
     180             : 
     181             : 
     182             : /* Detect the available hardware features.  This function is called
     183             :    once right at startup and we assume that no other threads are
     184             :    running.  */
     185             : void
     186          32 : _gcry_detect_hw_features (void)
     187             : {
     188          32 :   hw_features = 0;
     189             : 
     190          32 :   if (fips_mode ())
     191          32 :     return; /* Hardware support is not to be evaluated.  */
     192             : 
     193          32 :   parse_hwf_deny_file ();
     194             : 
     195             : #if defined (HAVE_CPU_ARCH_X86)
     196             :   {
     197          32 :     hw_features = _gcry_hwf_detect_x86 ();
     198             :   }
     199             : #endif /* HAVE_CPU_ARCH_X86 */
     200             : #if defined (HAVE_CPU_ARCH_ARM)
     201             :   {
     202             :     hw_features = _gcry_hwf_detect_arm ();
     203             :   }
     204             : #endif /* HAVE_CPU_ARCH_ARM */
     205             : 
     206          32 :   hw_features &= ~disabled_hw_features;
     207             : }

Generated by: LCOV version 1.11