LCOV - code coverage report
Current view: top level - src - fips.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 86 245 35.1 %
Date: 2017-03-02 16:44:37 Functions: 15 23 65.2 %

          Line data    Source code
       1             : /* fips.c - FIPS mode management
       2             :  * Copyright (C) 2008  Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of Libgcrypt.
       5             :  *
       6             :  * Libgcrypt is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser General Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Libgcrypt is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <errno.h>
      24             : #include <unistd.h>
      25             : #include <string.h>
      26             : #ifdef ENABLE_HMAC_BINARY_CHECK
      27             : # include <dlfcn.h>
      28             : #endif
      29             : #ifdef HAVE_SYSLOG
      30             : # include <syslog.h>
      31             : #endif /*HAVE_SYSLOG*/
      32             : 
      33             : #include "g10lib.h"
      34             : #include "cipher-proto.h"
      35             : #include "hmac256.h"
      36             : 
      37             : 
      38             : /* The name of the file used to force libgcrypt into fips mode. */
      39             : #define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
      40             : 
      41             : 
      42             : /* The states of the finite state machine used in fips mode.  */
      43             : enum module_states
      44             :   {
      45             :     /* POWEROFF cannot be represented.  */
      46             :     STATE_POWERON  = 0,
      47             :     STATE_INIT,
      48             :     STATE_SELFTEST,
      49             :     STATE_OPERATIONAL,
      50             :     STATE_ERROR,
      51             :     STATE_FATALERROR,
      52             :     STATE_SHUTDOWN
      53             :   };
      54             : 
      55             : 
      56             : /* Flag telling whether we are in fips mode.  It uses inverse logic so
      57             :    that fips mode is the default unless changed by the initialization
      58             :    code. To check whether fips mode is enabled, use the function
      59             :    fips_mode()! */
      60             : static int no_fips_mode_required;
      61             : 
      62             : /* Flag to indicate that we are in the enforced FIPS mode.  */
      63             : static int enforced_fips_mode;
      64             : 
      65             : /* If this flag is set, the application may no longer assume that the
      66             :    process is running in FIPS mode.  This flag is protected by the
      67             :    FSM_LOCK.  */
      68             : static int inactive_fips_mode;
      69             : 
      70             : /* This is the lock we use to protect the FSM.  */
      71             : GPGRT_LOCK_DEFINE (fsm_lock);
      72             : 
      73             : /* The current state of the FSM.  The whole state machinery is only
      74             :    used while in fips mode. Change this only while holding fsm_lock. */
      75             : static enum module_states current_state;
      76             : 
      77             : 
      78             : 
      79             : 
      80             : 
      81             : static void fips_new_state (enum module_states new_state);
      82             : 
      83             : 
      84             : 
      85             : /* Convert lowercase hex digits; assumes valid hex digits. */
      86             : #define loxtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): (*(p)-'a'+10))
      87             : #define loxtoi_2(p)   ((loxtoi_1(p) * 16) + loxtoi_1((p)+1))
      88             : 
      89             : /* Returns true if P points to a lowercase hex digit. */
      90             : #define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p))
      91             : 
      92             : 
      93             : 
      94             : /* Check whether the OS is in FIPS mode and record that in a module
      95             :    local variable.  If FORCE is passed as true, fips mode will be
      96             :    enabled anyway. Note: This function is not thread-safe and should
      97             :    be called before any threads are created.  This function may only
      98             :    be called once.  */
      99             : void
     100          34 : _gcry_initialize_fips_mode (int force)
     101             : {
     102             :   static int done;
     103             :   gpg_error_t err;
     104             : 
     105             :   /* Make sure we are not accidentally called twice.  */
     106          34 :   if (done)
     107             :     {
     108           0 :       if ( fips_mode () )
     109             :         {
     110           0 :           fips_new_state (STATE_FATALERROR);
     111           0 :           fips_noreturn ();
     112             :         }
     113             :       /* If not in fips mode an assert is sufficient.  */
     114           0 :       gcry_assert (!done);
     115             :     }
     116          34 :   done = 1;
     117             : 
     118             :   /* If the calling application explicitly requested fipsmode, do so.  */
     119          34 :   if (force)
     120             :     {
     121           0 :       gcry_assert (!no_fips_mode_required);
     122           0 :       goto leave;
     123             :     }
     124             : 
     125             :   /* For testing the system it is useful to override the system
     126             :      provided detection of the FIPS mode and force FIPS mode using a
     127             :      file.  The filename is hardwired so that there won't be any
     128             :      confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
     129             :      actually used.  The file itself may be empty.  */
     130          34 :   if ( !access (FIPS_FORCE_FILE, F_OK) )
     131             :     {
     132           0 :       gcry_assert (!no_fips_mode_required);
     133           0 :       goto leave;
     134             :     }
     135             : 
     136             :   /* Checking based on /proc file properties.  */
     137             :   {
     138             :     static const char procfname[] = "/proc/sys/crypto/fips_enabled";
     139             :     FILE *fp;
     140             :     int saved_errno;
     141             : 
     142          34 :     fp = fopen (procfname, "r");
     143          34 :     if (fp)
     144             :       {
     145             :         char line[256];
     146             : 
     147          34 :         if (fgets (line, sizeof line, fp) && atoi (line))
     148             :           {
     149             :             /* System is in fips mode.  */
     150           0 :             fclose (fp);
     151           0 :             gcry_assert (!no_fips_mode_required);
     152           0 :             goto leave;
     153             :           }
     154          34 :         fclose (fp);
     155             :       }
     156           0 :     else if ((saved_errno = errno) != ENOENT
     157           0 :              && saved_errno != EACCES
     158           0 :              && !access ("/proc/version", F_OK) )
     159             :       {
     160             :         /* Problem reading the fips file despite that we have the proc
     161             :            file system.  We better stop right away. */
     162           0 :         log_info ("FATAL: error reading `%s' in libgcrypt: %s\n",
     163             :                   procfname, strerror (saved_errno));
     164             : #ifdef HAVE_SYSLOG
     165           0 :         syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
     166             :                 "reading `%s' failed: %s - abort",
     167             :                 procfname, strerror (saved_errno));
     168             : #endif /*HAVE_SYSLOG*/
     169           0 :         abort ();
     170             :       }
     171             :   }
     172             : 
     173             :   /* Fips not not requested, set flag.  */
     174          34 :   no_fips_mode_required = 1;
     175             : 
     176             :  leave:
     177          34 :   if (!no_fips_mode_required)
     178             :     {
     179             :       /* Yes, we are in FIPS mode.  */
     180             :       FILE *fp;
     181             : 
     182             :       /* Intitialize the lock to protect the FSM.  */
     183           0 :       err = gpgrt_lock_init (&fsm_lock);
     184           0 :       if (err)
     185             :         {
     186             :           /* If that fails we can't do anything but abort the
     187             :              process. We need to use log_info so that the FSM won't
     188             :              get involved.  */
     189           0 :           log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
     190             :                     gpg_strerror (err));
     191             : #ifdef HAVE_SYSLOG
     192           0 :           syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
     193             :                   "creating FSM lock failed: %s - abort",
     194             :                   gpg_strerror (err));
     195             : #endif /*HAVE_SYSLOG*/
     196           0 :           abort ();
     197             :         }
     198             : 
     199             : 
     200             :       /* If the FIPS force files exists, is readable and has a number
     201             :          != 0 on its first line, we enable the enforced fips mode.  */
     202           0 :       fp = fopen (FIPS_FORCE_FILE, "r");
     203           0 :       if (fp)
     204             :         {
     205             :           char line[256];
     206             : 
     207           0 :           if (fgets (line, sizeof line, fp) && atoi (line))
     208           0 :             enforced_fips_mode = 1;
     209           0 :           fclose (fp);
     210             :         }
     211             : 
     212             :       /* Now get us into the INIT state.  */
     213           0 :       fips_new_state (STATE_INIT);
     214             : 
     215             :     }
     216          34 :   return;
     217             : }
     218             : 
     219             : static void
     220           4 : lock_fsm (void)
     221             : {
     222             :   gpg_error_t err;
     223             : 
     224           4 :   err = gpgrt_lock_lock (&fsm_lock);
     225           4 :   if (err)
     226             :     {
     227           0 :       log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n",
     228             :                 gpg_strerror (err));
     229             : #ifdef HAVE_SYSLOG
     230           0 :       syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
     231             :               "acquiring FSM lock failed: %s - abort",
     232             :               gpg_strerror (err));
     233             : #endif /*HAVE_SYSLOG*/
     234           0 :       abort ();
     235             :     }
     236           4 : }
     237             : 
     238             : static void
     239           4 : unlock_fsm (void)
     240             : {
     241             :   gpg_error_t err;
     242             : 
     243           4 :   err = gpgrt_lock_unlock (&fsm_lock);
     244           4 :   if (err)
     245             :     {
     246           0 :       log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n",
     247             :                 gpg_strerror (err));
     248             : #ifdef HAVE_SYSLOG
     249           0 :       syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
     250             :               "releasing FSM lock failed: %s - abort",
     251             :               gpg_strerror (err));
     252             : #endif /*HAVE_SYSLOG*/
     253           0 :       abort ();
     254             :     }
     255           4 : }
     256             : 
     257             : 
     258             : /* This function returns true if fips mode is enabled.  This is
     259             :    independent of the fips required finite state machine and only used
     260             :    to enable fips specific code.  Please use the fips_mode macro
     261             :    instead of calling this function directly. */
     262             : int
     263    41297041 : _gcry_fips_mode (void)
     264             : {
     265             :   /* No locking is required because we have the requirement that this
     266             :      variable is only initialized once with no other threads
     267             :      existing.  */
     268    41297041 :   return !no_fips_mode_required;
     269             : }
     270             : 
     271             : 
     272             : /* Return a flag telling whether we are in the enforced fips mode.  */
     273             : int
     274     1131844 : _gcry_enforced_fips_mode (void)
     275             : {
     276     1131844 :   if (!_gcry_fips_mode ())
     277     1131844 :     return 0;
     278           0 :   return enforced_fips_mode;
     279             : }
     280             : 
     281             : /* Set a flag telling whether we are in the enforced fips mode.  */
     282             : void
     283           0 : _gcry_set_enforced_fips_mode (void)
     284             : {
     285           0 :   enforced_fips_mode = 1;
     286           0 : }
     287             : 
     288             : /* If we do not want to enforce the fips mode, we can set a flag so
     289             :    that the application may check whether it is still in fips mode.
     290             :    TEXT will be printed as part of a syslog message.  This function
     291             :    may only be be called if in fips mode. */
     292             : void
     293           0 : _gcry_inactivate_fips_mode (const char *text)
     294             : {
     295           0 :   gcry_assert (_gcry_fips_mode ());
     296             : 
     297           0 :   if (_gcry_enforced_fips_mode () )
     298             :     {
     299             :       /* Get us into the error state. */
     300           0 :       fips_signal_error (text);
     301           0 :       return;
     302             :     }
     303             : 
     304           0 :   lock_fsm ();
     305           0 :   if (!inactive_fips_mode)
     306             :     {
     307           0 :       inactive_fips_mode = 1;
     308           0 :       unlock_fsm ();
     309             : #ifdef HAVE_SYSLOG
     310           0 :       syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
     311             :               "%s - FIPS mode inactivated", text);
     312             : #endif /*HAVE_SYSLOG*/
     313             :     }
     314             :   else
     315           0 :     unlock_fsm ();
     316             : }
     317             : 
     318             : 
     319             : /* Return the FIPS mode inactive flag.  If it is true the FIPS mode is
     320             :    not anymore active.  */
     321             : int
     322           4 : _gcry_is_fips_mode_inactive (void)
     323             : {
     324             :   int flag;
     325             : 
     326           4 :   if (!_gcry_fips_mode ())
     327           0 :     return 0;
     328           4 :   lock_fsm ();
     329           4 :   flag = inactive_fips_mode;
     330           4 :   unlock_fsm ();
     331           4 :   return flag;
     332             : }
     333             : 
     334             : 
     335             : 
     336             : static const char *
     337           0 : state2str (enum module_states state)
     338             : {
     339             :   const char *s;
     340             : 
     341           0 :   switch (state)
     342             :     {
     343           0 :     case STATE_POWERON:     s = "Power-On"; break;
     344           0 :     case STATE_INIT:        s = "Init"; break;
     345           0 :     case STATE_SELFTEST:    s = "Self-Test"; break;
     346           0 :     case STATE_OPERATIONAL: s = "Operational"; break;
     347           0 :     case STATE_ERROR:       s = "Error"; break;
     348           0 :     case STATE_FATALERROR:  s = "Fatal-Error"; break;
     349           0 :     case STATE_SHUTDOWN:    s = "Shutdown"; break;
     350           0 :     default:                s = "?"; break;
     351             :     }
     352           0 :   return s;
     353             : }
     354             : 
     355             : 
     356             : /* Return true if the library is in the operational state.  */
     357             : int
     358    39962994 : _gcry_fips_is_operational (void)
     359             : {
     360             :   int result;
     361             : 
     362    39962994 :   if (!fips_mode ())
     363    39962993 :     result = 1;
     364             :   else
     365             :     {
     366           0 :       lock_fsm ();
     367           0 :       if (current_state == STATE_INIT)
     368             :         {
     369             :           /* If we are still in the INIT state, we need to run the
     370             :              selftests so that the FSM can eventually get into
     371             :              operational state.  Given that we would need a 2-phase
     372             :              initialization of libgcrypt, but that has traditionally
     373             :              not been enforced, we use this on demand self-test
     374             :              checking.  Note that Proper applications would do the
     375             :              application specific libgcrypt initialization between a
     376             :              gcry_check_version() and gcry_control
     377             :              (GCRYCTL_INITIALIZATION_FINISHED) where the latter will
     378             :              run the selftests.  The drawback of these on-demand
     379             :              self-tests are a small chance that self-tests are
     380             :              performed by several threads; that is no problem because
     381             :              our FSM make sure that we won't oversee any error. */
     382           0 :           unlock_fsm ();
     383           0 :           _gcry_fips_run_selftests (0);
     384           0 :           lock_fsm ();
     385             :         }
     386             : 
     387           0 :       result = (current_state == STATE_OPERATIONAL);
     388           0 :       unlock_fsm ();
     389             :     }
     390    39962993 :   return result;
     391             : }
     392             : 
     393             : 
     394             : /* This is test on whether the library is in the operational state.  In
     395             :    contrast to _gcry_fips_is_operational this function won't do a
     396             :    state transition on the fly.  */
     397             : int
     398           0 : _gcry_fips_test_operational (void)
     399             : {
     400             :   int result;
     401             : 
     402           0 :   if (!fips_mode ())
     403           0 :     result = 1;
     404             :   else
     405             :     {
     406           0 :       lock_fsm ();
     407           0 :       result = (current_state == STATE_OPERATIONAL);
     408           0 :       unlock_fsm ();
     409             :     }
     410           0 :   return result;
     411             : }
     412             : 
     413             : 
     414             : /* This is a test on whether the library is in the error or
     415             :    operational state. */
     416             : int
     417           0 : _gcry_fips_test_error_or_operational (void)
     418             : {
     419             :   int result;
     420             : 
     421           0 :   if (!fips_mode ())
     422           0 :     result = 1;
     423             :   else
     424             :     {
     425           0 :       lock_fsm ();
     426           0 :       result = (current_state == STATE_OPERATIONAL
     427           0 :                 || current_state == STATE_ERROR);
     428           0 :       unlock_fsm ();
     429             :     }
     430           0 :   return result;
     431             : }
     432             : 
     433             : 
     434             : static void
     435          44 : reporter (const char *domain, int algo, const char *what, const char *errtxt)
     436             : {
     437          44 :   if (!errtxt && !_gcry_log_verbosity (2))
     438          44 :     return;
     439             : 
     440           0 :   log_info ("libgcrypt selftest: %s %s%s (%d): %s%s%s%s\n",
     441           0 :             !strcmp (domain, "hmac")? "digest":domain,
     442           0 :             !strcmp (domain, "hmac")? "HMAC-":"",
     443           0 :             !strcmp (domain, "cipher")? _gcry_cipher_algo_name (algo) :
     444           0 :             !strcmp (domain, "digest")? _gcry_md_algo_name (algo) :
     445           0 :             !strcmp (domain, "hmac")?   _gcry_md_algo_name (algo) :
     446           0 :             !strcmp (domain, "pubkey")? _gcry_pk_algo_name (algo) : "",
     447             :             algo, errtxt? errtxt:"Okay",
     448             :             what?" (":"", what? what:"", what?")":"");
     449             : }
     450             : 
     451             : /* Run self-tests for all required cipher algorithms.  Return 0 on
     452             :    success. */
     453             : static int
     454           2 : run_cipher_selftests (int extended)
     455             : {
     456             :   static int algos[] =
     457             :     {
     458             :       GCRY_CIPHER_3DES,
     459             :       GCRY_CIPHER_AES128,
     460             :       GCRY_CIPHER_AES192,
     461             :       GCRY_CIPHER_AES256,
     462             :       0
     463             :     };
     464             :   int idx;
     465             :   gpg_error_t err;
     466           2 :   int anyerr = 0;
     467             : 
     468          10 :   for (idx=0; algos[idx]; idx++)
     469             :     {
     470           8 :       err = _gcry_cipher_selftest (algos[idx], extended, reporter);
     471           8 :       reporter ("cipher", algos[idx], NULL,
     472             :                 err? gpg_strerror (err):NULL);
     473           8 :       if (err)
     474           0 :         anyerr = 1;
     475             :     }
     476           2 :   return anyerr;
     477             : }
     478             : 
     479             : 
     480             : /* Run self-tests for all required hash algorithms.  Return 0 on
     481             :    success. */
     482             : static int
     483           2 : run_digest_selftests (int extended)
     484             : {
     485             :   static int algos[] =
     486             :     {
     487             :       GCRY_MD_SHA1,
     488             :       GCRY_MD_SHA224,
     489             :       GCRY_MD_SHA256,
     490             :       GCRY_MD_SHA384,
     491             :       GCRY_MD_SHA512,
     492             :       0
     493             :     };
     494             :   int idx;
     495             :   gpg_error_t err;
     496           2 :   int anyerr = 0;
     497             : 
     498          12 :   for (idx=0; algos[idx]; idx++)
     499             :     {
     500          10 :       err = _gcry_md_selftest (algos[idx], extended, reporter);
     501          10 :       reporter ("digest", algos[idx], NULL,
     502             :                 err? gpg_strerror (err):NULL);
     503          10 :       if (err)
     504           0 :         anyerr = 1;
     505             :     }
     506           2 :   return anyerr;
     507             : }
     508             : 
     509             : 
     510             : /* Run self-tests for all HMAC algorithms.  Return 0 on success. */
     511             : static int
     512           2 : run_hmac_selftests (int extended)
     513             : {
     514             :   static int algos[] =
     515             :     {
     516             :       GCRY_MD_SHA1,
     517             :       GCRY_MD_SHA224,
     518             :       GCRY_MD_SHA256,
     519             :       GCRY_MD_SHA384,
     520             :       GCRY_MD_SHA512,
     521             :       GCRY_MD_SHA3_224,
     522             :       GCRY_MD_SHA3_256,
     523             :       GCRY_MD_SHA3_384,
     524             :       GCRY_MD_SHA3_512,
     525             :       0
     526             :     };
     527             :   int idx;
     528             :   gpg_error_t err;
     529           2 :   int anyerr = 0;
     530             : 
     531          20 :   for (idx=0; algos[idx]; idx++)
     532             :     {
     533          18 :       err = _gcry_hmac_selftest (algos[idx], extended, reporter);
     534          18 :       reporter ("hmac", algos[idx], NULL,
     535             :                 err? gpg_strerror (err):NULL);
     536          18 :       if (err)
     537           0 :         anyerr = 1;
     538             :     }
     539           2 :   return anyerr;
     540             : }
     541             : 
     542             : 
     543             : /* Run self-tests for all required public key algorithms.  Return 0 on
     544             :    success. */
     545             : static int
     546           2 : run_pubkey_selftests (int extended)
     547             : {
     548             :   static int algos[] =
     549             :     {
     550             :       GCRY_PK_RSA,
     551             :       GCRY_PK_DSA,
     552             :       GCRY_PK_ECC,
     553             :       0
     554             :     };
     555             :   int idx;
     556             :   gpg_error_t err;
     557           2 :   int anyerr = 0;
     558             : 
     559           8 :   for (idx=0; algos[idx]; idx++)
     560             :     {
     561           6 :       err = _gcry_pk_selftest (algos[idx], extended, reporter);
     562           6 :       reporter ("pubkey", algos[idx], NULL,
     563             :                 err? gpg_strerror (err):NULL);
     564           6 :       if (err)
     565           0 :         anyerr = 1;
     566             :     }
     567           2 :   return anyerr;
     568             : }
     569             : 
     570             : 
     571             : /* Run self-tests for the random number generator.  Returns 0 on
     572             :    success. */
     573             : static int
     574           2 : run_random_selftests (void)
     575             : {
     576             :   gpg_error_t err;
     577             : 
     578           2 :   err = _gcry_random_selftest (reporter);
     579           2 :   reporter ("random", 0, NULL, err? gpg_strerror (err):NULL);
     580             : 
     581           2 :   return !!err;
     582             : }
     583             : 
     584             : /* Run an integrity check on the binary.  Returns 0 on success.  */
     585             : static int
     586           2 : check_binary_integrity (void)
     587             : {
     588             : #ifdef ENABLE_HMAC_BINARY_CHECK
     589             :   gpg_error_t err;
     590             :   Dl_info info;
     591             :   unsigned char digest[32];
     592             :   int dlen;
     593             :   char *fname = NULL;
     594             :   const char key[] = "What am I, a doctor or a moonshuttle conductor?";
     595             : 
     596             :   if (!dladdr ("gcry_check_version", &info))
     597             :     err = gpg_error_from_syserror ();
     598             :   else
     599             :     {
     600             :       dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname,
     601             :                                  key, strlen (key));
     602             :       if (dlen < 0)
     603             :         err = gpg_error_from_syserror ();
     604             :       else if (dlen != 32)
     605             :         err = gpg_error (GPG_ERR_INTERNAL);
     606             :       else
     607             :         {
     608             :           fname = xtrymalloc (strlen (info.dli_fname) + 1 + 5 + 1 );
     609             :           if (!fname)
     610             :             err = gpg_error_from_syserror ();
     611             :           else
     612             :             {
     613             :               FILE *fp;
     614             :               char *p;
     615             : 
     616             :               /* Prefix the basename with a dot.  */
     617             :               strcpy (fname, info.dli_fname);
     618             :               p = strrchr (fname, '/');
     619             :               if (p)
     620             :                 p++;
     621             :               else
     622             :                 p = fname;
     623             :               memmove (p+1, p, strlen (p)+1);
     624             :               *p = '.';
     625             :               strcat (fname, ".hmac");
     626             : 
     627             :               /* Open the file.  */
     628             :               fp = fopen (fname, "r");
     629             :               if (!fp)
     630             :                 err = gpg_error_from_syserror ();
     631             :               else
     632             :                 {
     633             :                   /* A buffer of 64 bytes plus one for a LF and one to
     634             :                      detect garbage.  */
     635             :                   unsigned char buffer[64+1+1];
     636             :                   const unsigned char *s;
     637             :                   int n;
     638             : 
     639             :                   /* The HMAC files consists of lowercase hex digits
     640             :                      with an optional trailing linefeed or optional
     641             :                      with two trailing spaces.  The latter format
     642             :                      allows the use of the usual sha1sum format.  Fail
     643             :                      if there is any garbage.  */
     644             :                   err = gpg_error (GPG_ERR_SELFTEST_FAILED);
     645             :                   n = fread (buffer, 1, sizeof buffer, fp);
     646             :                   if (n == 64
     647             :                       || (n == 65 && buffer[64] == '\n')
     648             :                       || (n == 66 && buffer[64] == ' ' && buffer[65] == ' '))
     649             :                     {
     650             :                       buffer[64] = 0;
     651             :                       for (n=0, s= buffer;
     652             :                            n < 32 && loxdigit_p (s) && loxdigit_p (s+1);
     653             :                            n++, s += 2)
     654             :                         buffer[n] = loxtoi_2 (s);
     655             :                       if ( n == 32 && !memcmp (digest, buffer, 32) )
     656             :                         err = 0;
     657             :                     }
     658             :                   fclose (fp);
     659             :                 }
     660             :             }
     661             :         }
     662             :     }
     663             :   reporter ("binary", 0, fname, err? gpg_strerror (err):NULL);
     664             : #ifdef HAVE_SYSLOG
     665             :   if (err)
     666             :     syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
     667             :             "integrity check using `%s' failed: %s",
     668             :             fname? fname:"[?]", gpg_strerror (err));
     669             : #endif /*HAVE_SYSLOG*/
     670             :   xfree (fname);
     671             :   return !!err;
     672             : #else
     673           2 :   return 0;
     674             : #endif
     675             : }
     676             : 
     677             : 
     678             : /* Run the self-tests.  If EXTENDED is true, extended versions of the
     679             :    selftest are run, that is more tests than required by FIPS.  */
     680             : gpg_err_code_t
     681           2 : _gcry_fips_run_selftests (int extended)
     682             : {
     683           2 :   enum module_states result = STATE_ERROR;
     684           2 :   gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
     685             : 
     686           2 :   if (fips_mode ())
     687           0 :     fips_new_state (STATE_SELFTEST);
     688             : 
     689           2 :   if (run_cipher_selftests (extended))
     690           0 :     goto leave;
     691             : 
     692           2 :   if (run_digest_selftests (extended))
     693           0 :     goto leave;
     694             : 
     695           2 :   if (run_hmac_selftests (extended))
     696           0 :     goto leave;
     697             : 
     698             :   /* Run random tests before the pubkey tests because the latter
     699             :      require random.  */
     700           2 :   if (run_random_selftests ())
     701           0 :     goto leave;
     702             : 
     703           2 :   if (run_pubkey_selftests (extended))
     704           0 :     goto leave;
     705             : 
     706             :   /* Now check the integrity of the binary.  We do this this after
     707             :      having checked the HMAC code.  */
     708           2 :   if (check_binary_integrity ())
     709           0 :     goto leave;
     710             : 
     711             :   /* All selftests passed.  */
     712           2 :   result = STATE_OPERATIONAL;
     713           2 :   ec = 0;
     714             : 
     715             :  leave:
     716           2 :   if (fips_mode ())
     717           0 :     fips_new_state (result);
     718             : 
     719           2 :   return ec;
     720             : }
     721             : 
     722             : 
     723             : /* This function is used to tell the FSM about errors in the library.
     724             :    The FSM will be put into an error state.  This function should not
     725             :    be called directly but by one of the macros
     726             : 
     727             :      fips_signal_error (description)
     728             :      fips_signal_fatal_error (description)
     729             : 
     730             :    where DESCRIPTION is a string describing the error. */
     731             : void
     732           0 : _gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc,
     733             :                          int is_fatal, const char *description)
     734             : {
     735           0 :   if (!fips_mode ())
     736           0 :     return;  /* Not required.  */
     737             : 
     738             :   /* Set new state before printing an error.  */
     739           0 :   fips_new_state (is_fatal? STATE_FATALERROR : STATE_ERROR);
     740             : 
     741             :   /* Print error.  */
     742           0 :   log_info ("%serror in libgcrypt, file %s, line %d%s%s: %s\n",
     743             :             is_fatal? "fatal ":"",
     744             :             srcfile, srcline,
     745             :             srcfunc? ", function ":"", srcfunc? srcfunc:"",
     746             :             description? description : "no description available");
     747             : #ifdef HAVE_SYSLOG
     748           0 :   syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
     749             :           "%serror in file %s, line %d%s%s: %s",
     750             :           is_fatal? "fatal ":"",
     751             :           srcfile, srcline,
     752             :           srcfunc? ", function ":"", srcfunc? srcfunc:"",
     753             :           description? description : "no description available");
     754             : #endif /*HAVE_SYSLOG*/
     755             : }
     756             : 
     757             : 
     758             : /* Perform a state transition to NEW_STATE.  If this is an invalid
     759             :    transition, the module will go into a fatal error state. */
     760             : static void
     761           0 : fips_new_state (enum module_states new_state)
     762             : {
     763           0 :   int ok = 0;
     764             :   enum module_states last_state;
     765             : 
     766           0 :   lock_fsm ();
     767             : 
     768           0 :   last_state = current_state;
     769           0 :   switch (current_state)
     770             :     {
     771             :     case STATE_POWERON:
     772           0 :       if (new_state == STATE_INIT
     773           0 :           || new_state == STATE_ERROR
     774           0 :           || new_state == STATE_FATALERROR)
     775           0 :         ok = 1;
     776           0 :       break;
     777             : 
     778             :     case STATE_INIT:
     779           0 :       if (new_state == STATE_SELFTEST
     780           0 :           || new_state == STATE_ERROR
     781           0 :           || new_state == STATE_FATALERROR)
     782           0 :         ok = 1;
     783           0 :       break;
     784             : 
     785             :     case STATE_SELFTEST:
     786           0 :       if (new_state == STATE_OPERATIONAL
     787           0 :           || new_state == STATE_ERROR
     788           0 :           || new_state == STATE_FATALERROR)
     789           0 :         ok = 1;
     790           0 :       break;
     791             : 
     792             :     case STATE_OPERATIONAL:
     793           0 :       if (new_state == STATE_SHUTDOWN
     794           0 :           || new_state == STATE_SELFTEST
     795           0 :           || new_state == STATE_ERROR
     796           0 :           || new_state == STATE_FATALERROR)
     797           0 :         ok = 1;
     798           0 :       break;
     799             : 
     800             :     case STATE_ERROR:
     801           0 :       if (new_state == STATE_SHUTDOWN
     802           0 :           || new_state == STATE_ERROR
     803           0 :           || new_state == STATE_FATALERROR
     804           0 :           || new_state == STATE_SELFTEST)
     805           0 :         ok = 1;
     806           0 :       break;
     807             : 
     808             :     case STATE_FATALERROR:
     809           0 :       if (new_state == STATE_SHUTDOWN )
     810           0 :         ok = 1;
     811           0 :       break;
     812             : 
     813             :     case STATE_SHUTDOWN:
     814             :       /* We won't see any transition *from* Shutdown because the only
     815             :          allowed new state is Power-Off and that one can't be
     816             :          represented.  */
     817           0 :       break;
     818             : 
     819             :     }
     820             : 
     821           0 :   if (ok)
     822             :     {
     823           0 :       current_state = new_state;
     824             :     }
     825             : 
     826           0 :   unlock_fsm ();
     827             : 
     828           0 :   if (!ok || _gcry_log_verbosity (2))
     829           0 :     log_info ("libgcrypt state transition %s => %s %s\n",
     830             :               state2str (last_state), state2str (new_state),
     831             :               ok? "granted":"denied");
     832             : 
     833           0 :   if (!ok)
     834             :     {
     835             :       /* Invalid state transition.  Halting library. */
     836             : #ifdef HAVE_SYSLOG
     837           0 :       syslog (LOG_USER|LOG_ERR,
     838             :               "Libgcrypt error: invalid state transition %s => %s",
     839             :               state2str (last_state), state2str (new_state));
     840             : #endif /*HAVE_SYSLOG*/
     841           0 :       fips_noreturn ();
     842             :     }
     843           0 :   else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR)
     844             :     {
     845             : #ifdef HAVE_SYSLOG
     846           0 :       syslog (LOG_USER|LOG_WARNING,
     847             :               "Libgcrypt notice: state transition %s => %s",
     848             :               state2str (last_state), state2str (new_state));
     849             : #endif /*HAVE_SYSLOG*/
     850             :     }
     851           0 : }
     852             : 
     853             : 
     854             : 
     855             : 
     856             : /* This function should be called to ensure that the execution shall
     857             :    not continue. */
     858             : void
     859           0 : _gcry_fips_noreturn (void)
     860             : {
     861             : #ifdef HAVE_SYSLOG
     862           0 :   syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application");
     863             : #endif /*HAVE_SYSLOG*/
     864           0 :   fflush (NULL);
     865           0 :   abort ();
     866             :   /*NOTREACHED*/
     867             : }

Generated by: LCOV version 1.13