LCOV - code coverage report
Current view: top level - src - fips.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 72 245 29.4 %
Date: 2015-11-05 17:08:00 Functions: 12 23 52.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          31 : _gcry_initialize_fips_mode (int force)
     101             : {
     102             :   static int done;
     103             :   gpg_error_t err;
     104             : 
     105             :   /* Make sure we are not accidently called twice.  */
     106          31 :   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          31 :   done = 1;
     117             : 
     118             :   /* If the calling application explicitly requested fipsmode, do so.  */
     119          31 :   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          31 :   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          31 :     fp = fopen (procfname, "r");
     143          31 :     if (fp)
     144             :       {
     145             :         char line[256];
     146             : 
     147          31 :         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          31 :         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          31 :   no_fips_mode_required = 1;
     175             : 
     176             :  leave:
     177          31 :   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          31 :   return;
     217             : }
     218             : 
     219             : static void
     220           0 : lock_fsm (void)
     221             : {
     222             :   gpg_error_t err;
     223             : 
     224           0 :   err = gpgrt_lock_lock (&fsm_lock);
     225           0 :   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           0 : }
     237             : 
     238             : static void
     239           0 : unlock_fsm (void)
     240             : {
     241             :   gpg_error_t err;
     242             : 
     243           0 :   err = gpgrt_lock_unlock (&fsm_lock);
     244           0 :   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           0 : }
     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    32219956 : _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    32219956 :   return !no_fips_mode_required;
     269             : }
     270             : 
     271             : 
     272             : /* Return a flag telling whether we are in the enforced fips mode.  */
     273             : int
     274      649718 : _gcry_enforced_fips_mode (void)
     275             : {
     276      649718 :   if (!_gcry_fips_mode ())
     277      649718 :     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           0 : _gcry_is_fips_mode_inactive (void)
     323             : {
     324             :   int flag;
     325             : 
     326           0 :   if (!_gcry_fips_mode ())
     327           0 :     return 0;
     328           0 :   lock_fsm ();
     329           0 :   flag = inactive_fips_mode;
     330           0 :   unlock_fsm ();
     331           0 :   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    31439990 : _gcry_fips_is_operational (void)
     359             : {
     360             :   int result;
     361             : 
     362    31439990 :   if (!fips_mode ())
     363    31439994 :     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 severeal 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    31439994 :   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          21 : reporter (const char *domain, int algo, const char *what, const char *errtxt)
     436             : {
     437          21 :   if (!errtxt && !_gcry_log_verbosity (2))
     438          42 :     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           1 : 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           1 :   int anyerr = 0;
     467             : 
     468           5 :   for (idx=0; algos[idx]; idx++)
     469             :     {
     470           4 :       err = _gcry_cipher_selftest (algos[idx], extended, reporter);
     471           4 :       reporter ("cipher", algos[idx], NULL,
     472             :                 err? gpg_strerror (err):NULL);
     473           4 :       if (err)
     474           0 :         anyerr = 1;
     475             :     }
     476           1 :   return anyerr;
     477             : }
     478             : 
     479             : 
     480             : /* Run self-tests for all required hash algorithms.  Return 0 on
     481             :    success. */
     482             : static int
     483           1 : 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           1 :   int anyerr = 0;
     497             : 
     498           6 :   for (idx=0; algos[idx]; idx++)
     499             :     {
     500           5 :       err = _gcry_md_selftest (algos[idx], extended, reporter);
     501           5 :       reporter ("digest", algos[idx], NULL,
     502             :                 err? gpg_strerror (err):NULL);
     503           5 :       if (err)
     504           0 :         anyerr = 1;
     505             :     }
     506           1 :   return anyerr;
     507             : }
     508             : 
     509             : 
     510             : /* Run self-tests for all HMAC algorithms.  Return 0 on success. */
     511             : static int
     512           1 : 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           1 :   int anyerr = 0;
     530             : 
     531          10 :   for (idx=0; algos[idx]; idx++)
     532             :     {
     533           9 :       err = _gcry_hmac_selftest (algos[idx], extended, reporter);
     534           9 :       reporter ("hmac", algos[idx], NULL,
     535             :                 err? gpg_strerror (err):NULL);
     536           9 :       if (err)
     537           0 :         anyerr = 1;
     538             :     }
     539           1 :   return anyerr;
     540             : }
     541             : 
     542             : 
     543             : /* Run self-tests for all required public key algorithms.  Return 0 on
     544             :    success. */
     545             : static int
     546           1 : run_pubkey_selftests (int extended)
     547             : {
     548             :   static int algos[] =
     549             :     {
     550             :       GCRY_PK_RSA,
     551             :       GCRY_PK_DSA,
     552             :       /* GCRY_PK_ECC is not enabled in fips mode.  */
     553             :       0
     554             :     };
     555             :   int idx;
     556             :   gpg_error_t err;
     557           1 :   int anyerr = 0;
     558             : 
     559           3 :   for (idx=0; algos[idx]; idx++)
     560             :     {
     561           2 :       err = _gcry_pk_selftest (algos[idx], extended, reporter);
     562           2 :       reporter ("pubkey", algos[idx], NULL,
     563             :                 err? gpg_strerror (err):NULL);
     564           2 :       if (err)
     565           0 :         anyerr = 1;
     566             :     }
     567           1 :   return anyerr;
     568             : }
     569             : 
     570             : 
     571             : /* Run self-tests for the random number generator.  Returns 0 on
     572             :    success. */
     573             : static int
     574           1 : run_random_selftests (void)
     575             : {
     576             :   gpg_error_t err;
     577             : 
     578           1 :   err = _gcry_random_selftest (reporter);
     579           1 :   reporter ("random", 0, NULL, err? gpg_strerror (err):NULL);
     580             : 
     581           1 :   return !!err;
     582             : }
     583             : 
     584             : /* Run an integrity check on the binary.  Returns 0 on success.  */
     585             : static int
     586           1 : 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             :                      only with an optional trailing linefeed.  Fail if
     641             :                      there is any garbage.  */
     642             :                   err = gpg_error (GPG_ERR_SELFTEST_FAILED);
     643             :                   n = fread (buffer, 1, sizeof buffer, fp);
     644             :                   if (n == 64 || (n == 65 && buffer[64] == '\n'))
     645             :                     {
     646             :                       buffer[64] = 0;
     647             :                       for (n=0, s= buffer;
     648             :                            n < 32 && loxdigit_p (s) && loxdigit_p (s+1);
     649             :                            n++, s += 2)
     650             :                         buffer[n] = loxtoi_2 (s);
     651             :                       if ( n == 32 && !memcmp (digest, buffer, 32) )
     652             :                         err = 0;
     653             :                     }
     654             :                   fclose (fp);
     655             :                 }
     656             :             }
     657             :         }
     658             :     }
     659             :   reporter ("binary", 0, fname, err? gpg_strerror (err):NULL);
     660             : #ifdef HAVE_SYSLOG
     661             :   if (err)
     662             :     syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
     663             :             "integrity check using `%s' failed: %s",
     664             :             fname? fname:"[?]", gpg_strerror (err));
     665             : #endif /*HAVE_SYSLOG*/
     666             :   xfree (fname);
     667             :   return !!err;
     668             : #else
     669           1 :   return 0;
     670             : #endif
     671             : }
     672             : 
     673             : 
     674             : /* Run the self-tests.  If EXTENDED is true, extended versions of the
     675             :    selftest are run, that is more tests than required by FIPS.  */
     676             : gpg_err_code_t
     677           1 : _gcry_fips_run_selftests (int extended)
     678             : {
     679           1 :   enum module_states result = STATE_ERROR;
     680           1 :   gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
     681             : 
     682           1 :   if (fips_mode ())
     683           0 :     fips_new_state (STATE_SELFTEST);
     684             : 
     685           1 :   if (run_cipher_selftests (extended))
     686           0 :     goto leave;
     687             : 
     688           1 :   if (run_digest_selftests (extended))
     689           0 :     goto leave;
     690             : 
     691           1 :   if (run_hmac_selftests (extended))
     692           0 :     goto leave;
     693             : 
     694             :   /* Run random tests before the pubkey tests because the latter
     695             :      require random.  */
     696           1 :   if (run_random_selftests ())
     697           0 :     goto leave;
     698             : 
     699           1 :   if (run_pubkey_selftests (extended))
     700           0 :     goto leave;
     701             : 
     702             :   /* Now check the integrity of the binary.  We do this this after
     703             :      having checked the HMAC code.  */
     704           1 :   if (check_binary_integrity ())
     705           0 :     goto leave;
     706             : 
     707             :   /* All selftests passed.  */
     708           1 :   result = STATE_OPERATIONAL;
     709           1 :   ec = 0;
     710             : 
     711             :  leave:
     712           1 :   if (fips_mode ())
     713           0 :     fips_new_state (result);
     714             : 
     715           1 :   return ec;
     716             : }
     717             : 
     718             : 
     719             : /* This function is used to tell the FSM about errors in the library.
     720             :    The FSM will be put into an error state.  This function should not
     721             :    be called directly but by one of the macros
     722             : 
     723             :      fips_signal_error (description)
     724             :      fips_signal_fatal_error (description)
     725             : 
     726             :    where DESCRIPTION is a string describing the error. */
     727             : void
     728           0 : _gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc,
     729             :                          int is_fatal, const char *description)
     730             : {
     731           0 :   if (!fips_mode ())
     732           0 :     return;  /* Not required.  */
     733             : 
     734             :   /* Set new state before printing an error.  */
     735           0 :   fips_new_state (is_fatal? STATE_FATALERROR : STATE_ERROR);
     736             : 
     737             :   /* Print error.  */
     738           0 :   log_info ("%serror in libgcrypt, file %s, line %d%s%s: %s\n",
     739             :             is_fatal? "fatal ":"",
     740             :             srcfile, srcline,
     741             :             srcfunc? ", function ":"", srcfunc? srcfunc:"",
     742             :             description? description : "no description available");
     743             : #ifdef HAVE_SYSLOG
     744           0 :   syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
     745             :           "%serror in file %s, line %d%s%s: %s",
     746             :           is_fatal? "fatal ":"",
     747             :           srcfile, srcline,
     748             :           srcfunc? ", function ":"", srcfunc? srcfunc:"",
     749             :           description? description : "no description available");
     750             : #endif /*HAVE_SYSLOG*/
     751             : }
     752             : 
     753             : 
     754             : /* Perform a state transition to NEW_STATE.  If this is an invalid
     755             :    transition, the module will go into a fatal error state. */
     756             : static void
     757           0 : fips_new_state (enum module_states new_state)
     758             : {
     759           0 :   int ok = 0;
     760             :   enum module_states last_state;
     761             : 
     762           0 :   lock_fsm ();
     763             : 
     764           0 :   last_state = current_state;
     765           0 :   switch (current_state)
     766             :     {
     767             :     case STATE_POWERON:
     768           0 :       if (new_state == STATE_INIT
     769           0 :           || new_state == STATE_ERROR
     770           0 :           || new_state == STATE_FATALERROR)
     771           0 :         ok = 1;
     772           0 :       break;
     773             : 
     774             :     case STATE_INIT:
     775           0 :       if (new_state == STATE_SELFTEST
     776           0 :           || new_state == STATE_ERROR
     777           0 :           || new_state == STATE_FATALERROR)
     778           0 :         ok = 1;
     779           0 :       break;
     780             : 
     781             :     case STATE_SELFTEST:
     782           0 :       if (new_state == STATE_OPERATIONAL
     783           0 :           || new_state == STATE_ERROR
     784           0 :           || new_state == STATE_FATALERROR)
     785           0 :         ok = 1;
     786           0 :       break;
     787             : 
     788             :     case STATE_OPERATIONAL:
     789           0 :       if (new_state == STATE_SHUTDOWN
     790           0 :           || new_state == STATE_SELFTEST
     791           0 :           || new_state == STATE_ERROR
     792           0 :           || new_state == STATE_FATALERROR)
     793           0 :         ok = 1;
     794           0 :       break;
     795             : 
     796             :     case STATE_ERROR:
     797           0 :       if (new_state == STATE_SHUTDOWN
     798           0 :           || new_state == STATE_ERROR
     799           0 :           || new_state == STATE_FATALERROR
     800           0 :           || new_state == STATE_SELFTEST)
     801           0 :         ok = 1;
     802           0 :       break;
     803             : 
     804             :     case STATE_FATALERROR:
     805           0 :       if (new_state == STATE_SHUTDOWN )
     806           0 :         ok = 1;
     807           0 :       break;
     808             : 
     809             :     case STATE_SHUTDOWN:
     810             :       /* We won't see any transition *from* Shutdown because the only
     811             :          allowed new state is Power-Off and that one can't be
     812             :          represented.  */
     813           0 :       break;
     814             : 
     815             :     }
     816             : 
     817           0 :   if (ok)
     818             :     {
     819           0 :       current_state = new_state;
     820             :     }
     821             : 
     822           0 :   unlock_fsm ();
     823             : 
     824           0 :   if (!ok || _gcry_log_verbosity (2))
     825           0 :     log_info ("libgcrypt state transition %s => %s %s\n",
     826             :               state2str (last_state), state2str (new_state),
     827             :               ok? "granted":"denied");
     828             : 
     829           0 :   if (!ok)
     830             :     {
     831             :       /* Invalid state transition.  Halting library. */
     832             : #ifdef HAVE_SYSLOG
     833           0 :       syslog (LOG_USER|LOG_ERR,
     834             :               "Libgcrypt error: invalid state transition %s => %s",
     835             :               state2str (last_state), state2str (new_state));
     836             : #endif /*HAVE_SYSLOG*/
     837           0 :       fips_noreturn ();
     838             :     }
     839           0 :   else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR)
     840             :     {
     841             : #ifdef HAVE_SYSLOG
     842           0 :       syslog (LOG_USER|LOG_WARNING,
     843             :               "Libgcrypt notice: state transition %s => %s",
     844             :               state2str (last_state), state2str (new_state));
     845             : #endif /*HAVE_SYSLOG*/
     846             :     }
     847           0 : }
     848             : 
     849             : 
     850             : 
     851             : 
     852             : /* This function should be called to ensure that the execution shall
     853             :    not continue. */
     854             : void
     855           0 : _gcry_fips_noreturn (void)
     856             : {
     857             : #ifdef HAVE_SYSLOG
     858           0 :   syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application");
     859             : #endif /*HAVE_SYSLOG*/
     860           0 :   fflush (NULL);
     861           0 :   abort ();
     862             :   /*NOTREACHED*/
     863             : }

Generated by: LCOV version 1.11