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

Generated by: LCOV version 1.13