[svn] gcry - r1304 - in trunk: . doc random src tests

svn author wk cvs at cvs.gnupg.org
Fri Aug 22 21:17:06 CEST 2008


Author: wk
Date: 2008-08-22 21:17:05 +0200 (Fri, 22 Aug 2008)
New Revision: 1304

Modified:
   trunk/ChangeLog
   trunk/README
   trunk/configure.ac
   trunk/doc/gcrypt.texi
   trunk/random/ChangeLog
   trunk/random/rand-internal.h
   trunk/random/random-fips.c
   trunk/random/random.c
   trunk/random/random.h
   trunk/src/ChangeLog
   trunk/src/Makefile.am
   trunk/src/cipher-proto.h
   trunk/src/fips.c
   trunk/src/global.c
   trunk/src/hmac256.c
   trunk/src/hmac256.h
   trunk/tests/Makefile.am
Log:
Completed the RNG implementaion switching.
Added framework for running RNG tests.
Added an experimental option --enable-hmac-binary-check to configure.
 --This line, and those below, will be ignored--

M    src/fips.c
M    src/cipher-proto.h
M    src/global.c
M    src/hmac256.c
M    src/ChangeLog
M    src/hmac256.h
M    src/Makefile.am
M    tests/Makefile.am
M    configure.ac
M    doc/gcrypt.texi
M    random/random-fips.c
M    random/random.c
M    random/rand-internal.h
M    random/random.h
M    random/ChangeLog
M    ChangeLog
M    README


[The diff below has been truncated]

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/ChangeLog	2008-08-22 19:17:05 UTC (rev 1304)
@@ -1,3 +1,8 @@
+2008-08-22  Werner Koch  <wk at g10code.com>
+
+	* configure.ac: Add option --enable-hmac-binary-check.
+	(DL_LIBS): Check whether -ldl is required.
+
 2008-08-19  Werner Koch  <wk at g10code.com>
 
 	Release 1.4.2rc1.

Modified: trunk/random/ChangeLog
===================================================================
--- trunk/random/ChangeLog	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/random/ChangeLog	2008-08-22 19:17:05 UTC (rev 1304)
@@ -1,3 +1,11 @@
+2008-08-22  Werner Koch  <wk at g10code.com>
+
+	* random.c (_gcry_update_random_seed_file): Move operational check
+	to _gcry_vcontrol.
+	(_gcry_fast_random_poll): Ditto.
+	(_gcry_random_selftest): New.
+	* random-fips.c (_gcry_rngfips_selftest): New.
+
 2008-08-21  Werner Koch  <wk at g10code.com>
 
 	* random-fips.c: Finish implementation.

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/src/ChangeLog	2008-08-22 19:17:05 UTC (rev 1304)
@@ -1,3 +1,14 @@
+2008-08-22  Werner Koch  <wk at g10code.com>
+
+	* hmac256.c (_gcry_hmac256_file): New.
+	(main): New option --binary.
+	* fips.c (check_binary_integrity): New.
+	(_gcry_fips_run_selftests): Run it.
+
+	* global.c (_gcry_vcontrol) <GCRYCTL_UPDATE_RANDOM_SEED_FILE>:
+	Check for fips operational state.
+	(_gcry_vcontrol) <GCRYCTL_FAST_POLL>: Ditt.
+
 2008-08-21  Werner Koch  <wk at g10code.com>
 
 	* misc.c (_gcry_log_printhex): New.

Modified: trunk/README
===================================================================
--- trunk/README	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/README	2008-08-22 19:17:05 UTC (rev 1304)
@@ -158,12 +158,18 @@
                       auto - Compile linux, egd and unix in and 
                              automagically select at runtime.
   
+     --enable-hmac-binary-check
+                     Include support to check the binary at runtime
+                     against a HMAC checksum.  This works only in FIPS
+                     mode and on systems providing the dladdr function.
+
      --disable-padlock-support
                      Disable support for the PadLock engine of VIA
                      processors.  The default is to use PadLock if
                      available.  Try this if you get problems with
                      assembler code.
 
+       
 
 
     License

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/configure.ac	2008-08-22 19:17:05 UTC (rev 1304)
@@ -449,7 +449,20 @@
             [use_capabilities="$withval"],[use_capabilities=no])
 AC_MSG_RESULT($use_capabilities)
 
+# Implementation of the --enable-hmac-binary-check.
+AC_MSG_CHECKING([whether a HMAC binary check is requested])
+AC_ARG_ENABLE(hmac-binary-check,
+              AC_HELP_STRING([--enable-hmac-binary-check],
+                             [Enable library integrity check]),
+              [use_hmac_binary_check=$enableval],
+              [use_hmac_binary_check=no])
+AC_MSG_RESULT($use_hmac_binary_check)
+if test "$use_hmac_binary_check" = yes ; then
+    AC_DEFINE(ENABLE_HMAC_BINARY_CHECK,1,
+              [Define to support an HMAC based integrity check])
+fi
 
+
 # Implementation of the --disable-padlock-support switch.
 AC_MSG_CHECKING([whether padlock support is requested])
 AC_ARG_ENABLE(padlock-support,
@@ -692,7 +705,25 @@
 
 GNUPG_CHECK_MLOCK
 
+
+#
+# Check wether it is necessary to link against libdl.
+#
+DL_LIBS=""
+if test "$use_hmac_binary_check" = yes ; then
+  _gcry_save_libs="$LIBS"
+  LIBS=""
+  AC_SEARCH_LIBS(dlopen, c dl,,,)
+  DL_LIBS=$LIBS
+  LIBS="$_gcry_save_libs"
+  LIBGCRYPT_CONFIG_LIBS="${LIBGCRYPT_CONFIG_LIBS} ${DL_LIBS}"
+fi
+AC_SUBST(DL_LIBS)
+
+
+#
 # Check whether we can use Linux capabilities as requested.
+#
 if test "$use_capabilities" = "yes" ; then
 use_capabilities=no
 AC_CHECK_HEADERS(sys/capability.h)

Modified: trunk/doc/gcrypt.texi
===================================================================
--- trunk/doc/gcrypt.texi	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/doc/gcrypt.texi	2008-08-22 19:17:05 UTC (rev 1304)
@@ -4607,7 +4607,9 @@
 
 @itemize
 
- at item  TBD
+ at item 
+It may only be used on systesm with a /dev/random device.  Swicthing
+into FIPS mode on other systems will fail at runtime.
 
 
 

Modified: trunk/random/rand-internal.h
===================================================================
--- trunk/random/rand-internal.h	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/random/rand-internal.h	2008-08-22 19:17:05 UTC (rev 1304)
@@ -20,6 +20,7 @@
 #ifndef G10_RAND_INTERNAL_H
 #define G10_RAND_INTERNAL_H
 
+#include "../src/cipher-proto.h"
 
 /* Constants used to define the origin of random added to the pool.
    The code is sensitive to the order of the values.  */
@@ -76,11 +77,13 @@
                                 enum gcry_random_level level);
 void _gcry_rngfips_create_nonce (void *buffer, size_t length);
 
+gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report);
 
 
 
 
 
+
 /*-- rndlinux.c --*/
 int _gcry_rndlinux_gather_random (void (*add) (const void *, size_t,
                                                enum random_origins),

Modified: trunk/random/random-fips.c
===================================================================
--- trunk/random/random-fips.c	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/random/random-fips.c	2008-08-22 19:17:05 UTC (rev 1304)
@@ -602,6 +602,7 @@
 }
 
 
+
 /* Initialize this random subsystem.  If FULL is false, this function
    merely calls the basic initialization of the module and does not do
    anything more.  Doing this is not really required but when running
@@ -639,9 +640,11 @@
 }
 
 
+/* Print some statistics about the RNG.  */
 void
 _gcry_rngfips_dump_stats (void)
 {
+  /* Not yet implemented.  */
 }
 
 
@@ -656,11 +659,11 @@
 
 /* Add BUFLEN bytes from BUF to the internal random pool.  QUALITY
    should be in the range of 0..100 to indicate the goodness of the
-   entropy added, or -1 for goodness not known.  */
+   entropy added, or -1 for goodness not known. */
 gcry_error_t
 _gcry_rngfips_add_bytes (const void *buf, size_t buflen, int quality)
 {
-  return 0;
+  return 0;  /* Not implemented. */
 }   
 
     
@@ -691,3 +694,18 @@
   get_random (buffer, length, nonce_context);
 }
 
+
+/* Run the self-tests.  */
+gcry_error_t
+_gcry_rngfips_selftest (selftest_report_func_t report)
+{
+  gcry_err_code_t ec = 0;
+  char buffer[8];
+
+  /* Do a simple test using the public interface.  */
+  gcry_randomize (buffer, sizeof buffer, GCRY_STRONG_RANDOM);
+
+
+  return gpg_error (ec);
+}
+

Modified: trunk/random/random.c
===================================================================
--- trunk/random/random.c	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/random/random.c	2008-08-22 19:17:05 UTC (rev 1304)
@@ -75,7 +75,7 @@
 void
 _gcry_random_initialize (int full)
 {
-  if ( fips_mode() )
+  if (fips_mode ())
     _gcry_rngfips_initialize (full);
   else
     _gcry_rngcsprng_initialize (full);
@@ -85,7 +85,7 @@
 void
 _gcry_random_dump_stats (void)
 {
-  if ( fips_mode() )
+  if (fips_mode ())
     _gcry_rngfips_dump_stats ();
   else
     _gcry_rngcsprng_dump_stats ();
@@ -98,9 +98,10 @@
 void
 _gcry_secure_random_alloc (void)
 {
-  if ( fips_mode() )
-    return;  /* Not used; the fips rng is allows in secure mode.  */
-  _gcry_rngcsprng_secure_alloc ();
+  if (fips_mode ())
+    ;  /* Not used; the fips rng is allows in secure mode.  */
+  else
+    _gcry_rngcsprng_secure_alloc ();
 }
 
 
@@ -109,18 +110,20 @@
 void
 _gcry_enable_quick_random_gen (void)
 {
-  if ( fips_mode() )
-    return;  /* Not used.  */
-  _gcry_rngcsprng_enable_quick_gen ();
+  if (fips_mode ())
+    ;  /* Not used.  */
+  else
+    _gcry_rngcsprng_enable_quick_gen ();
 }
 
 
 void
 _gcry_set_random_daemon_socket (const char *socketname)
 {
-  if ( fips_mode() )
-    return;  /* Not used.  */
-  _gcry_rngcsprng_set_daemon_socket (socketname);
+  if (fips_mode ())
+    ;  /* Not used.  */
+  else
+    _gcry_rngcsprng_set_daemon_socket (socketname);
 }
 
 /* With ONOFF set to 1, enable the use of the daemon.  With ONOFF set
@@ -131,7 +134,8 @@
 {
   if (fips_mode ())
     return 0; /* Never enabled in fips mode.  */
-  return _gcry_rngcsprng_use_daemon (onoff);
+  else
+    return _gcry_rngcsprng_use_daemon (onoff);
 }
 
 
@@ -141,8 +145,9 @@
 _gcry_random_is_faked (void)
 {
   if (fips_mode ())
-    return 0; /* Never faked in fips mode.  */
-  return _gcry_rngcsprng_is_faked ();
+    return _gcry_rngfips_is_faked ();
+  else
+    return _gcry_rngcsprng_is_faked ();
 }
 
 
@@ -154,7 +159,8 @@
 {
   if (fips_mode ())
     return 0; /* No need for this in fips mode.  */
-  return _gcry_rngcsprng_add_bytes (buf, buflen, quality);
+  else
+    return _gcry_rngcsprng_add_bytes (buf, buflen, quality);
 }   
 
   
@@ -217,7 +223,10 @@
 void
 _gcry_set_random_seed_file (const char *name)
 {
-  _gcry_rngcsprng_set_seed_file (name);
+  if (fips_mode ())
+    ; /* No need for this in fips mode.  */
+  else
+    _gcry_rngcsprng_set_seed_file (name);
 }
 
 
@@ -226,10 +235,10 @@
 void
 _gcry_update_random_seed_file (void)
 {
-  if (!fips_is_operational ())  /* FIXME:  This does no look correct.  */
-    return;
-
-  _gcry_rngcsprng_update_seed_file ();
+  if (fips_mode ())
+    ; /* No need for this in fips mode.  */
+  else
+    _gcry_rngcsprng_update_seed_file ();
 }
 
 
@@ -244,10 +253,10 @@
 void
 _gcry_fast_random_poll (void)
 {
-  if (!fips_is_operational ())
-    return;
-
-  _gcry_rngcsprng_fast_poll ();
+  if (fips_mode ())
+    ; /* No need for this in fips mode.  */
+  else
+    _gcry_rngcsprng_fast_poll ();
 }
 
 
@@ -256,6 +265,21 @@
 void
 gcry_create_nonce (void *buffer, size_t length)
 {
-  _gcry_rngcsprng_create_nonce (buffer, length);
+  if (fips_mode ())
+    _gcry_rngfips_create_nonce (buffer, length);
+  else
+    _gcry_rngcsprng_create_nonce (buffer, length);
 }
 
+
+/* Run the self-tests for the RNG.  This is currently only implemented
+   for the FIPS generator.  */
+gpg_error_t
+_gcry_random_selftest (selftest_report_func_t report)
+{
+  if (fips_mode ())
+    return _gcry_rngfips_selftest (report);
+  else
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+}
+

Modified: trunk/random/random.h
===================================================================
--- trunk/random/random.h	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/random/random.h	2008-08-22 19:17:05 UTC (rev 1304)
@@ -22,6 +22,7 @@
 
 #include "types.h"
 
+/*-- random.c --*/
 void _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
                                      void *cb_data );
 
@@ -38,6 +39,7 @@
 byte *_gcry_get_random_bits( size_t nbits, int level, int secure );
 void _gcry_fast_random_poll( void );
 
+
 /*-- rndegd.c --*/
 gpg_error_t _gcry_rndegd_set_socket_name (const char *name);
 

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/src/Makefile.am	2008-08-22 19:17:05 UTC (rev 1304)
@@ -121,3 +121,12 @@
 install-data-local: install-def-file
 
 uninstall-local: uninstall-def-file
+
+# FIXME: We ned to figure out how to gte the actual name (parsing
+# libgcrypt.la?) and how to create the hmac file already at link time
+# so that it can be used without first installing.
+#install-exec-hook:
+#	./hmac256 --binary "What am I, a doctor or a moonshuttle conductor?" \
+#           $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \
+#          >$(DESTDIR)$(libdir)/libgcrypt.so.11.5.0.hmac
+

Modified: trunk/src/cipher-proto.h
===================================================================
--- trunk/src/cipher-proto.h	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/src/cipher-proto.h	2008-08-22 19:17:05 UTC (rev 1304)
@@ -79,5 +79,6 @@
 gcry_error_t _gcry_pk_selftest (int algo, selftest_report_func_t report);
 gcry_error_t _gcry_hmac_selftest (int algo, selftest_report_func_t report);
 
+gcry_error_t _gcry_random_selftest (selftest_report_func_t report);
 
 #endif /*G10_CIPHER_PROTO_H*/

Modified: trunk/src/fips.c
===================================================================
--- trunk/src/fips.c	2008-08-21 18:34:24 UTC (rev 1303)
+++ trunk/src/fips.c	2008-08-22 19:17:05 UTC (rev 1304)
@@ -22,12 +22,14 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
+#ifdef ENABLE_HMAC_BINARY_CHECK
+# include <dlfcn.h> 
+#endif
 
-/* #include <dlfcn.h>  /\* FIXME:  GNU only *\/ */
-
 #include "g10lib.h"
 #include "ath.h"
 #include "cipher-proto.h"
+#include "hmac256.h"
 
 /* The states of the finite state machine used in fips mode.  */
 enum module_states 
@@ -417,17 +419,79 @@
 }
 
 
-/* Run self-tests for the random number generator.  Return 0 on
+/* Run self-tests for the random number generator.  Returns 0 on
    success. */
 static int
 run_random_selftests (void)
 {
-  char buffer[8];
+  gpg_error_t err;
 
-  /* FIXME: For now we just try to get a few bytes.  */
-  gcry_randomize (buffer, sizeof buffer, GCRY_STRONG_RANDOM);
+  err = _gcry_random_selftest (reporter);
+  reporter ("random", 0, NULL, err? gpg_strerror (err):NULL);
+  
+  return !!err;
+}
 
+/* Run an integrity check on the binary.  Returns 0 on success.  */
+static int
+check_binary_integrity (void)
+{
+#ifdef ENABLE_HMAC_BINARY_CHECK
+  gpg_error_t err;
+  Dl_info info;
+  unsigned char digest[32];
+  int dlen;
+  char *fname = NULL;
+  const char key[] = "What am I, a doctor or a moonshuttle conductor?";
+  
+  if (!dladdr ("gcry_check_version", &info))
+    err = gpg_error_from_syserror ();
+  else
+    {
+      dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname,
+                                 key, strlen (key));
+      if (dlen < 0)
+        err = gpg_error_from_syserror ();
+      else if (dlen != 32)
+        err = gpg_error (GPG_ERR_INTERNAL);
+      else
+        {
+          FILE *fp;
+  
+          fname = gcry_malloc (strlen (info.dli_fname) + 5 + 1 );
+          if (!fname)
+            err = gpg_error_from_syserror ();
+          else
+            {
+              strcpy (stpcpy (fname, info.dli_fname), ".hmac");
+              fp = fopen (fname, "rb");
+              if (!fp)
+                err = gpg_error_from_syserror ();
+              else
+                {
+                  char buffer[33];
+                  int n;
+
+                  /* We expect a file of exactly 32 bytes.  Consider
+                     the self-test failed if this is not the case or
+                     if it does not match the just computed HMAC.  */
+                  if ((n=fread (buffer, 1, 33, fp)) != 32
+                      || memcmp (digest, buffer, 32) )
+                    err = gpg_error (GPG_ERR_SELFTEST_FAILED);
+                  else
+                    err = 0;
+
+                  fclose (fp);
+                }
+            }
+        }
+    }
+  reporter ("binary", 0, fname, err? gpg_strerror (err):NULL);
+  gcry_free (fname);
+  return !!err;
+#else
   return 0;
+#endif
 }
 
 
@@ -439,15 +503,6 @@
   
   fips_new_state (STATE_SELFTEST);
 
-/*   { */
-/*     Dl_info info; */




More information about the Gnupg-commits mailing list