[git] GCRYPT - branch, master, updated. libgcrypt-1.7.3-106-g27148e6

by Werner Koch cvs at cvs.gnupg.org
Wed Jun 21 09:47:41 CEST 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".

The branch, master has been updated
       via  27148e60ba15b0cb73b47a75c688fcb48a1a3444 (commit)
       via  c2319464b03e61aaf34ef6d5f4b59b0c0483a373 (commit)
      from  32b4ab209067f6f08b87b27bc78ec27dc497b708 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 27148e60ba15b0cb73b47a75c688fcb48a1a3444
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Jun 21 09:29:09 2017 +0200

    api: New function gcry_get_config.
    
    * src/misc.c (_gcry_log_info_with_dummy_fp): Remove.
    * src/global.c (print_config): New arg WHAT.  Remove arg FNC and use
    gpgrt_fprintf directly.
    (_gcry_get_config): New.
    (_gcry_vcontrol) <GCRYCTL_PRINT_CONFIG>: Use _gcry_get_config instead
    of print_config.
    * src/gcrypt.h.in (gcry_get_config): New.
    * src/libgcrypt.def, src/libgcrypt.vers: Add new function.
    * src/visibility.c (gcry_get_config): New.
    * src/visibility.h: Mark new function.
    
    * tests/version.c (test_get_config): New.
    (main): Call new test.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index d7e9bd9..c97f425 100644
--- a/NEWS
+++ b/NEWS
@@ -67,6 +67,7 @@ Noteworthy changes in version 1.8.0 (unreleased)  [C21/A1/R_]
  * Interface changes relative to the 1.7.0 release:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    GCRYCTL_REINIT_SYSCALL_CLAMP    NEW macro.
+   gcry_get_config                 NEW function.
    gcry_md_info                    DEPRECATED.
 
 
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index 26dd6c3..cab1318 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -824,7 +824,8 @@ proper random device.
 This command dumps information pertaining to the configuration of the
 library to the given stream.  If NULL is given for @var{stream}, the log
 system is used.  This command may be used before the initialization has
-been finished but not before a @code{gcry_check_version}.
+been finished but not before a @code{gcry_check_version}.  Note that
+the macro @code{estream_t} can be used instead of @code{gpgrt_stream_t}.
 
 @item GCRYCTL_OPERATIONAL_P; Arguments: none
 This command returns true if the library is in an operational state.
@@ -5233,6 +5234,7 @@ wrong.
 * Memory allocation::   Functions related with memory allocation.
 * Context management::  Functions related with context management.
 * Buffer description::  A data type to describe buffers.
+* Config reporting::    How to return Libgcrypt's configuration.
 @end menu
 
 
@@ -5317,6 +5319,27 @@ of this structure are:
   @end table
 @end deftp
 
+ at node Config reporting
+ at section How to return Libgcrypt's configuration.
+
+Although @code{GCRYCTL_PRINT_CONFIG} can be used to print
+configuration options, it is sometimes necessary to check them in a
+program.  This can be accomplished by using this function:
+
+ at deftypefun {char *} gcry_get_config @
+             (@w{int @var{mode}}, @
+             @w{const char *@var{what}})
+
+This function returns a malloced string with colon delimited configure
+options.  With a value of 0 for @var{mode} this string resembles the
+output of @code{GCRYCTL_PRINT_CONFIG}.  However, if @var{what} is not
+NULL, only the line where the first field (e.g. "cpu-arch") matches
+ at var{what} is returned.
+
+Other values than 0 for @var{mode} are not defined.  The caller shall
+free the string using @code{gcry_free}.  On error NULL is returned and
+ERRNO is set; if a value for WHAT is unknow ERRNO will be set to 0.
+ at end deftypefun
 
 
 @c **********************************************************
diff --git a/src/g10lib.h b/src/g10lib.h
index ec8aab5..961b515 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -109,6 +109,8 @@ void _gcry_pre_syscall (void);
 void _gcry_post_syscall (void);
 int _gcry_get_debug_flag (unsigned int mask);
 
+char *_gcry_get_config (int mode, const char *what);
+
 /* Malloc functions and common wrapper macros.  */
 void *_gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
 void *_gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
@@ -163,8 +165,6 @@ void _gcry_log_bug( const char *fmt, ... )   JNLIB_GCC_A_NR_PRINTF(1,2);
 void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
 void _gcry_log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
 void _gcry_log_info( const char *fmt, ... )  JNLIB_GCC_A_PRINTF(1,2);
-int  _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
-                                             JNLIB_GCC_A_PRINTF(2,3);
 void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
 void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
 void _gcry_log_printhex (const char *text, const void *buffer, size_t length);
@@ -174,6 +174,7 @@ void _gcry_log_printsxp (const char *text, gcry_sexp_t sexp);
 void _gcry_set_log_verbosity( int level );
 int _gcry_log_verbosity( int level );
 
+
 #ifdef JNLIB_GCC_M_FUNCTION
 #define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ )
 #define gcry_assert(expr) (LIKELY(expr)? (void)0 \
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 210ea2f..8d20c83 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -1691,6 +1691,7 @@ void gcry_log_debugpnt (const char *text,
                         gcry_mpi_point_t point, gcry_ctx_t ctx);
 void gcry_log_debugsxp (const char *text, gcry_sexp_t sexp);
 
+char *gcry_get_config (int mode, const char *what);
 
 /* Log levels used by the internal logging facility. */
 enum gcry_log_levels
diff --git a/src/global.c b/src/global.c
index 0796a94..4e2e274 100644
--- a/src/global.c
+++ b/src/global.c
@@ -2,7 +2,7 @@
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
  *               2004, 2005, 2006, 2008, 2011,
  *               2012  Free Software Foundation, Inc.
- * Copyright (C) 2013, 2014 g10 Code GmbH
+ * Copyright (C) 2013, 2014, 2017 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -273,91 +273,181 @@ _gcry_check_version (const char *req_version)
 
 
 static void
-print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
+print_config (const char *what, gpgrt_stream_t fp)
 {
-  unsigned int hwfeatures, afeature;
   int i;
   const char *s;
 
-  fnc (fp, "version:%s:%x:%s:%x:\n",
-       VERSION, GCRYPT_VERSION_NUMBER,
-       GPGRT_VERSION, GPGRT_VERSION_NUMBER);
-  fnc (fp, "cc:%d:%s:\n",
+  if (!what || !strcmp (what, "version"))
+    {
+      gpgrt_fprintf (fp, "version:%s:%x:%s:%x:\n",
+                     VERSION, GCRYPT_VERSION_NUMBER,
+                     GPGRT_VERSION, GPGRT_VERSION_NUMBER);
+    }
+  if (!what || !strcmp (what, "cc"))
+    {
+      gpgrt_fprintf (fp, "cc:%d:%s:\n",
 #if GPGRT_VERSION_NUMBER >= 0x011b00 /* 1.27 */
-       GPGRT_GCC_VERSION
+                     GPGRT_GCC_VERSION
 #else
-       _GPG_ERR_GCC_VERSION /* Due to a bug in gpg-error.h.  */
+                     _GPG_ERR_GCC_VERSION /* Due to a bug in gpg-error.h.  */
 #endif
-       ,
+                     ,
 #ifdef __clang__
-       "clang:" __VERSION__
+                     "clang:" __VERSION__
 #elif __GNUC__
-       "gcc:" __VERSION__
+                     "gcc:" __VERSION__
 #else
-       ":"
+                     ":"
 #endif
-       );
+                     );
+    }
 
-  fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
-  fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
-  fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
-  fnc (fp, "rnd-mod:"
+  if (!what || !strcmp (what, "ciphers"))
+    gpgrt_fprintf (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
+  if (!what || !strcmp (what, "pubkeys"))
+    gpgrt_fprintf (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
+  if (!what || !strcmp (what, "digests"))
+    gpgrt_fprintf (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
+
+  if (!what || !strcmp (what, "rnd-mod"))
+    {
+      gpgrt_fprintf (fp, "rnd-mod:"
 #if USE_RNDEGD
-                "egd:"
+                     "egd:"
 #endif
 #if USE_RNDLINUX
-                "linux:"
+                     "linux:"
 #endif
 #if USE_RNDUNIX
-                "unix:"
+                     "unix:"
 #endif
 #if USE_RNDW32
-                "w32:"
+                     "w32:"
 #endif
-       "\n");
-  fnc (fp, "cpu-arch:"
+                     "\n");
+    }
+
+  if (!what || !strcmp (what, "cpu-arch"))
+    {
+      gpgrt_fprintf (fp, "cpu-arch:"
 #if defined(HAVE_CPU_ARCH_X86)
-       "x86"
+                     "x86"
 #elif defined(HAVE_CPU_ARCH_ALPHA)
-       "alpha"
+                     "alpha"
 #elif defined(HAVE_CPU_ARCH_SPARC)
-       "sparc"
+                     "sparc"
 #elif defined(HAVE_CPU_ARCH_MIPS)
-       "mips"
+                     "mips"
 #elif defined(HAVE_CPU_ARCH_M68K)
-       "m68k"
+                     "m68k"
 #elif defined(HAVE_CPU_ARCH_PPC)
-       "ppc"
+                     "ppc"
 #elif defined(HAVE_CPU_ARCH_ARM)
-       "arm"
+                     "arm"
 #endif
-       ":\n");
-  fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
-  hwfeatures = _gcry_get_hw_features ();
-  fnc (fp, "hwflist:");
-  for (i=0; (s = _gcry_enum_hw_features (i, &afeature)); i++)
-    if ((hwfeatures & afeature))
-      fnc (fp, "%s:", s);
-  fnc (fp, "\n");
-  /* We use y/n instead of 1/0 for the simple reason that Emacsen's
-     compile error parser would accidentally flag that line when printed
-     during "make check" as an error.  */
-  fnc (fp, "fips-mode:%c:%c:\n",
-       fips_mode ()? 'y':'n',
-       _gcry_enforced_fips_mode ()? 'y':'n' );
-  /* The currently used RNG type.  */
-  {
-    i = _gcry_get_rng_type (0);
-    switch (i)
-      {
-      case GCRY_RNG_TYPE_STANDARD: s = "standard"; break;
-      case GCRY_RNG_TYPE_FIPS:     s = "fips"; break;
-      case GCRY_RNG_TYPE_SYSTEM:   s = "system"; break;
-      default: BUG ();
-      }
-    fnc (fp, "rng-type:%s:%d:\n", s, i);
-  }
+                     ":\n");
+    }
+
+  if (!what || !strcmp (what, "mpi-asm"))
+    gpgrt_fprintf (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
+
+  if (!what || !strcmp (what, "hwflist"))
+    {
+      unsigned int hwfeatures, afeature;
+
+      hwfeatures = _gcry_get_hw_features ();
+      gpgrt_fprintf (fp, "hwflist:");
+      for (i=0; (s = _gcry_enum_hw_features (i, &afeature)); i++)
+        if ((hwfeatures & afeature))
+          gpgrt_fprintf (fp, "%s:", s);
+      gpgrt_fprintf (fp, "\n");
+    }
+
+  if (!what || !strcmp (what, "fips-mode"))
+    {
+      /* We use y/n instead of 1/0 for the stupid reason that
+       * Emacsen's compile error parser would accidentally flag that
+       * line when printed during "make check" as an error.  */
+      gpgrt_fprintf (fp, "fips-mode:%c:%c:\n",
+                     fips_mode ()? 'y':'n',
+                     _gcry_enforced_fips_mode ()? 'y':'n' );
+    }
+
+  if (!what || !strcmp (what, "rng-type"))
+    {
+      /* The currently used RNG type.  */
+      unsigned int jver;
+      int active;
+
+      i = _gcry_get_rng_type (0);
+      switch (i)
+        {
+        case GCRY_RNG_TYPE_STANDARD: s = "standard"; break;
+        case GCRY_RNG_TYPE_FIPS:     s = "fips"; break;
+        case GCRY_RNG_TYPE_SYSTEM:   s = "system"; break;
+        default: BUG ();
+        }
+      jver = _gcry_rndjent_get_version (&active);
+      gpgrt_fprintf (fp, "rng-type:%s:%d:%u:%d:\n", s, i, jver, active);
+    }
+}
+
+
+/* With a MODE of 0 return a malloced string with configured features.
+ * In that case a WHAT of NULL returns everything in the same way
+ * GCRYCTL_PRINT_CONFIG would do.  With a specific WHAT string only
+ * the requested feature is returned (w/o the trailing LF.  On error
+ * NULL is returned.  */
+char *
+_gcry_get_config (int mode, const char *what)
+{
+  gpgrt_stream_t fp;
+  int save_errno;
+  void *data;
+  char *p;
+
+  if (mode)
+    {
+      gpg_err_set_errno (EINVAL);
+      return NULL;
+    }
+
+  fp = gpgrt_fopenmem (0, "w+b,samethread");
+  if (!fp)
+    return NULL;
+
+  print_config (what, fp);
+  if (gpgrt_ferror (fp))
+    {
+      save_errno = errno;
+      gpgrt_fclose (fp);
+      gpg_err_set_errno (save_errno);
+      return NULL;
+    }
+
+  gpgrt_rewind (fp);
+  if (gpgrt_fclose_snatch (fp, &data, NULL))
+    {
+      save_errno = errno;
+      gpgrt_fclose (fp);
+      gpg_err_set_errno (save_errno);
+      return NULL;
+    }
+
+  if (!data)
+    {
+      /* Nothing was printed (unknown value for WHAT).  This is okay,
+       * so clear ERRNO to indicate this. */
+      gpg_err_set_errno (0);
+      return NULL;
+    }
+
+  /* Strip trailing LF.  */
+  if (what && (p = strchr (data, '\n')))
+    *p = 0;
 
+  return data;
 }
 
 
@@ -549,12 +639,21 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       /* This command dumps information pertaining to the
          configuration of libgcrypt to the given stream.  It may be
          used before the initialization has been finished but not
-         before a gcry_version_check. */
+         before a gcry_version_check.  See also gcry_get_config.  */
     case GCRYCTL_PRINT_CONFIG:
       {
         FILE *fp = va_arg (arg_ptr, FILE *);
+        char *tmpstr;
         _gcry_set_preferred_rng_type (0);
-        print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp);
+        tmpstr = _gcry_get_config (0, NULL);
+        if (tmpstr)
+          {
+            if (fp)
+              fputs (tmpstr, fp);
+            else
+              log_info ("%s", tmpstr);
+            xfree (tmpstr);
+          }
       }
       break;
 
diff --git a/src/libgcrypt.def b/src/libgcrypt.def
index 067cb84..c4a9eac 100644
--- a/src/libgcrypt.def
+++ b/src/libgcrypt.def
@@ -282,4 +282,6 @@ EXPORTS
 
       gcry_mpi_ec_decode_point  @246
 
+      gcry_get_config           @247
+
 ;; end of file with public symbols for Windows.
diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers
index 785b8ed..1d2d150 100644
--- a/src/libgcrypt.vers
+++ b/src/libgcrypt.vers
@@ -111,6 +111,8 @@ GCRYPT_1.6 {
     gcry_log_debug;
     gcry_log_debughex; gcry_log_debugmpi; gcry_log_debugpnt; gcry_log_debugsxp;
 
+    gcry_get_config;
+
     _gcry_mpi_get_const;
 
     gcry_ctx_release;
diff --git a/src/misc.c b/src/misc.c
index 9d8b7bd..002a84f 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -198,18 +198,6 @@ _gcry_log_info( const char *fmt, ... )
     va_end(arg_ptr);
 }
 
-int
-_gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
-{
-    va_list arg_ptr;
-
-    (void)fp;
-    va_start( arg_ptr, fmt ) ;
-    _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
-    va_end(arg_ptr);
-    return 0;
-}
-
 void
 _gcry_log_error( const char *fmt, ... )
 {
diff --git a/src/visibility.c b/src/visibility.c
index 3abbd37..7bf3d57 100644
--- a/src/visibility.c
+++ b/src/visibility.c
@@ -1435,6 +1435,12 @@ gcry_log_debugsxp (const char *text, gcry_sexp_t sexp)
   _gcry_log_printsxp (text, sexp);
 }
 
+char *
+gcry_get_config (int mode, const char *what)
+{
+  return _gcry_get_config (mode, what);
+}
+
 void
 gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data)
 {
diff --git a/src/visibility.h b/src/visibility.h
index 7ecd75e..d28993a 100644
--- a/src/visibility.h
+++ b/src/visibility.h
@@ -279,6 +279,8 @@ MARK_VISIBLEX (gcry_log_debugmpi)
 MARK_VISIBLEX (gcry_log_debugpnt)
 MARK_VISIBLEX (gcry_log_debugsxp)
 
+MARK_VISIBLEX (gcry_get_config)
+
 /* Functions used to implement macros.  */
 MARK_VISIBLEX (_gcry_mpi_get_const)
 
diff --git a/tests/version.c b/tests/version.c
index baf984e..6a01610 100644
--- a/tests/version.c
+++ b/tests/version.c
@@ -32,12 +32,58 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <errno.h>
 
 #include "../src/gcrypt-int.h"
 
 #define PGM "version"
 #include "t-common.h"
 
+static void
+test_get_config (void)
+{
+  char *string;
+
+  string = gcry_get_config (0, NULL);
+  if (!string)
+    fail ("gcry_get_config does not return anything: %s\n",
+          gpg_strerror (gpg_error_from_syserror ()));
+  else if ( !strchr (string, '\n') )
+    fail ("gcry_get_config(0, NULL) did not return multiple lines\n");
+
+  xfree (string);
+  string = gcry_get_config (0, "version");
+  if (!string)
+    fail ("gcry_get_config(\"version\") returned NULL: %s\n",
+          gpg_strerror (gpg_error_from_syserror ()));
+  else if ( strchr (string, '\n') )
+    fail ("gcry_get_config(\"version\") returned more than one line\n");
+  else if ( strncmp (string, "version:", 8) )
+    fail ("gcry_get_config(\"version\") returned wrong line\n");
+
+  /* Test an item which is not the first.  */
+  xfree (string);
+  string = gcry_get_config (0, "cpu-arch");
+  if (!string)
+    fail ("gcry_get_config(\"cpu-arch\") returned NULL: %s\n",
+          gpg_strerror (gpg_error_from_syserror ()));
+  else if ( strchr (string, '\n') )
+    fail ("gcry_get_config(\"cpu-arch\") returned more than one line\n");
+  else if ( strncmp (string, "cpu-arch:", 9) )
+    fail ("gcry_get_config(\"cpu-arch\") returned wrong line\n");
+
+  /* Test that an unknown item return sthe correct error.  */
+  xfree (string);
+  string = gcry_get_config (0, "no-such-item");
+  if (string)
+    fail ("gcry_get_config(\"no-such-item\") returned something\n");
+  else if (errno)
+    fail ("gcry_get_config(\"no-such-item\") returned wrong error: %s\n",
+          gpg_strerror (gpg_error_from_syserror ()));
+
+  xfree (string);
+}
+
 
 int
 main (int argc, char **argv)
@@ -96,5 +142,8 @@ main (int argc, char **argv)
 
   xgcry_control (GCRYCTL_PRINT_CONFIG, NULL);
 
+  test_get_config ();
+
+
   return 0;
 }

commit c2319464b03e61aaf34ef6d5f4b59b0c0483a373
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Jun 21 09:24:42 2017 +0200

    random: Allow building rndjent on non-x86.
    
    * random/jitterentropy-base.c (jent_version): Uncomment function.
    * random/rndjent.c: Include time.h
    (JENT_USES_RDTSC): New.
    (JENT_USES_GETTIME): New.
    (JENT_USES_READ_REAL_TIME): New.
    (jent_get_nstime): Support clock_gettime and AIX specific
    function.  Taken from Stephan Müller's code.
    (is_rng_available): New.
    (_gcry_rndjent_dump_stats): Use that function.
    (_gcry_rndjent_poll): Use that fucntion.  Allow an ADD of NULL for an
    intialize only mode.
    (_gcry_rndjent_get_version): New.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/random/jitterentropy-base.c b/random/jitterentropy-base.c
index e80ca6e..2701e90 100644
--- a/random/jitterentropy-base.c
+++ b/random/jitterentropy-base.c
@@ -81,8 +81,7 @@
  *
  * Return: Version number of kcapi library
  */
-#if 0
-unsigned int jent_version(void)
+static unsigned int jent_version(void)
 {
         unsigned int version = 0;
 
@@ -92,7 +91,6 @@ unsigned int jent_version(void)
 
         return version;
 }
-#endif
 
 /**
  * Update of the loop count used for the next round of
diff --git a/random/random.h b/random/random.h
index 30e6fdf..af99346 100644
--- a/random/random.h
+++ b/random/random.h
@@ -65,6 +65,10 @@ gpg_err_code_t _gcry_rngdrbg_healthcheck_one (struct gcry_drbg_test_vector *t);
 /*-- rndegd.c --*/
 gpg_error_t _gcry_rndegd_set_socket_name (const char *name);
 
+/*-- rndjent.c --*/
+unsigned int _gcry_rndjent_get_version (int *r_active);
+
+
 /*-- random-daemon.c (only used from random.c) --*/
 #ifdef USE_RANDOM_DAEMON
 void _gcry_daemon_initialize_basics (void);
diff --git a/random/rndjent.c b/random/rndjent.c
index 86dc88e..dd7ad04 100644
--- a/random/rndjent.c
+++ b/random/rndjent.c
@@ -39,6 +39,7 @@
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 #ifdef HAVE_STDINT_H
 # include <stdint.h>
 #endif
@@ -52,9 +53,18 @@
  * Decide whether we can support jent at compile time.
  */
 #undef USE_JENT
+#define JENT_USES_RDTSC 1
+#define JENT_USES_GETTIME 2
+#define JENT_USES_READ_REAL_TIME 3
 #ifdef ENABLE_JENT_SUPPORT
 # if defined (__i386__) || defined(__x86_64__)
-#   define USE_JENT 1
+#   define USE_JENT JENT_USES_RDTSC
+# elif defined (HAVE_CLOCK_GETTIME)
+#  if _AIX
+#   define USE_JENT JENT_USES_READ_REAL_TIME
+#  else
+#   define USE_JENT JENT_USES_GETTIME
+#  endif
 # endif
 #endif /*ENABLE_JENT_SUPPORT*/
 
@@ -78,12 +88,50 @@
 static void
 jent_get_nstime(u64 *out)
 {
+#if USE_JENT == JENT_USES_RDTSC
+
   u32 t_eax, t_edx;
 
   asm volatile (".byte 0x0f,0x31\n\t"
                 : "=a" (t_eax), "=d" (t_edx)
                 );
   *out = (((u64)t_edx << 32) | t_eax);
+
+#elif USE_JENT == JENT_USES_GETTIME
+
+  struct timespec tv;
+  u64 tmp;
+
+  /* On Linux we could use CLOCK_MONOTONIC(_RAW), but with
+   * CLOCK_REALTIME we get some nice extra entropy once in a while
+   * from the NTP actions that we want to use as well... though, we do
+   * not rely on that extra little entropy.  */
+  if (!clock_gettime (CLOCK_REALTIME, &tv))
+    {
+      tmp = time.tv_sec;
+      tmp = tmp << 32;
+      tmp = tmp | time.tv_nsec;
+    }
+  else
+    tmp = 0;
+  *out = tmp;
+
+#elif USE_JENT == JENT_USES_READ_REAL_TIME
+
+  /* clock_gettime() on AIX returns a timer value that increments in
+   * steps of 1000.  */
+  u64 tmp = 0;
+
+  timebasestruct_t aixtime;
+  read_real_time (&aixtime, TIMEBASE_SZ);
+  tmp = aixtime.tb_high;
+  tmp = tmp << 32;
+  tmp = tmp | aixtime.tb_low;
+  *out = tmp;
+
+#else
+# error No clock available in jent_get_nstime
+#endif
 }
 
 
@@ -267,6 +315,23 @@ unlock_rng (void)
                gpg_strerror (rc));
 }
 
+
+/* Return true if the JENT RNG code can be run.  It may not yet been
+ * initialized, though.  */
+static int
+is_rng_available (void)
+{
+#if USE_JENT == JENT_USES_RDTSC
+  return !!(_gcry_get_hw_features () & HWF_INTEL_RDTSC);
+#elif USE_JENT == JENT_USES_GETTIME
+  return 2;
+#elif USE_JENT == JENT_USES_READ_REAL_TIME
+  return 3;
+#else  /* Ooops  */
+  return 0;
+#endif
+}
+
 #endif /* USE_JENT */
 
 

@@ -282,11 +347,8 @@ _gcry_rndjent_poll (void (*add)(const void*, size_t, enum random_origins),
 {
   size_t nbytes = 0;
 
-  (void)add;
-  (void)origin;
-
 #ifdef USE_JENT
-  if ((_gcry_get_hw_features () & HWF_INTEL_RDTSC))
+  if ( is_rng_available () )
     {
       lock_rng ();
 
@@ -303,7 +365,7 @@ _gcry_rndjent_poll (void (*add)(const void*, size_t, enum random_origins),
             }
         }
 
-      if (jent_rng_collector)
+      if (jent_rng_collector && add)
         {
           /* We have a working JENT and it has not been disabled.  */
           char buffer[32];
@@ -331,12 +393,46 @@ _gcry_rndjent_poll (void (*add)(const void*, size_t, enum random_origins),
 
       unlock_rng ();
     }
+
+#else
+
+  (void)add;
+  (void)origin;
+
 #endif
 
   return nbytes;
 }
 
 
+/* Return the version number of the JENT RNG.  If the RNG is not
+ * initialized or usable 0 is returned.  If R_ACTIVE is not NULL the
+ * jitter RNG will be initialized and true is stored at R_ACTIVE if
+ * the initialization succeeded.  */
+unsigned int
+_gcry_rndjent_get_version (int *r_active)
+{
+#ifdef USE_JENT
+  if ( is_rng_available () )
+    {
+      if (r_active)
+        {
+          /* Make sure the RNG is initialized.  */
+          _gcry_rndjent_poll (NULL, 0, 0);
+          /* To ease debugging we store 2 for a clock_gettime based
+           * implementation and 1 for a rdtsc based code.  */
+          *r_active = jent_rng_collector? is_rng_available () : 0;
+        }
+      return jent_version ();
+    }
+  else
+    return 0;
+#else
+  return 0;
+#endif
+}
+
+
 /* Log statistical informantion about the use of this module.  */
 void
 _gcry_rndjent_dump_stats (void)
@@ -346,9 +442,8 @@ _gcry_rndjent_dump_stats (void)
      into problems.  */
 
 #ifdef USE_JENT
-  if ((_gcry_get_hw_features () & HWF_INTEL_RDTSC))
+  if ( is_rng_available () )
     {
-
       log_info ("rndjent stat: collector=%p calls=%lu bytes=%lu\n",
                 jent_rng_collector, jent_rng_totalcalls, jent_rng_totalbytes);
 

-----------------------------------------------------------------------

Summary of changes:
 NEWS                        |   1 +
 doc/gcrypt.texi             |  25 ++++-
 random/jitterentropy-base.c |   4 +-
 random/random.h             |   4 +
 random/rndjent.c            | 111 ++++++++++++++++++++--
 src/g10lib.h                |   5 +-
 src/gcrypt.h.in             |   1 +
 src/global.c                | 217 ++++++++++++++++++++++++++++++++------------
 src/libgcrypt.def           |   2 +
 src/libgcrypt.vers          |   2 +
 src/misc.c                  |  12 ---
 src/visibility.c            |   6 ++
 src/visibility.h            |   2 +
 tests/version.c             |  49 ++++++++++
 14 files changed, 356 insertions(+), 85 deletions(-)


hooks/post-receive
-- 
The GNU crypto library
http://git.gnupg.org


_______________________________________________
Gnupg-commits mailing list
Gnupg-commits at gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-commits


More information about the Gcrypt-devel mailing list