]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Hardening: periodically reset the PRNG's nonce value
authorAdriaan de Jong <dejong@fox-it.com>
Tue, 5 Jul 2011 11:50:48 +0000 (13:50 +0200)
committerDavid Sommerseth <davids@redhat.com>
Sat, 22 Oct 2011 15:22:51 +0000 (17:22 +0200)
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>
crypto.c
crypto.h

index 0ec321a5fecd75194575c0bd9fbbb1ccbcc063bf..6f0a44e770f23bdbdcdb98396e5836a8d5da8595 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -1260,6 +1260,24 @@ static uint8_t *nonce_data = NULL; /* GLOBAL */
 static const md_kt_t *nonce_md = NULL; /* GLOBAL */
 static int nonce_secret_len = 0; /* GLOBAL */
 
+/* Reset the nonce value, also done periodically to refresh entropy */
+static void
+prng_reset_nonce ()
+{
+  const int size = md_kt_size (nonce_md) + nonce_secret_len;
+#if 1 /* Must be 1 for real usage */
+  if (!rand_bytes (nonce_data, size))
+    msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for PRNG");
+#else
+    /* Only for testing -- will cause a predictable PRNG sequence */
+    {
+      int i;
+      for (i = 0; i < size; ++i)
+       nonce_data[i] = (uint8_t) i;
+    }
+#endif
+}
+
 void
 prng_init (const char *md_name, const int nonce_secret_len_parm)
 {
@@ -1274,17 +1292,7 @@ prng_init (const char *md_name, const int nonce_secret_len_parm)
        dmsg (D_CRYPTO_DEBUG, "PRNG init md=%s size=%d", md_kt_name(nonce_md), size);
        nonce_data = (uint8_t*) malloc (size);
        check_malloc_return (nonce_data);
-#if 1 /* Must be 1 for real usage */
-       if (!rand_bytes (nonce_data, size))
-         msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for PRNG");
-#else
-       /* Only for testing -- will cause a predictable PRNG sequence */
-       {
-         int i;
-         for (i = 0; i < size; ++i)
-           nonce_data[i] = (uint8_t) i;
-       }
-#endif
+       prng_reset_nonce();
       }
     }
 }
@@ -1301,6 +1309,8 @@ prng_uninit (void)
 void
 prng_bytes (uint8_t *output, int len)
 {
+  static int32_t processed = 0;
+
   if (nonce_md)
     {
       md_ctx_t ctx;
@@ -1313,6 +1323,13 @@ prng_bytes (uint8_t *output, int len)
          memcpy (output, nonce_data, blen);
          output += blen;
          len -= blen;
+
+         /* Ensure that random data is reset regularly */
+         processed += blen;
+         if(processed > PRNG_NONCE_RESET_BYTES) {
+           prng_reset_nonce();
+           processed = 0;
+         }
        }
     }
   else
index c037ad9900745c42bac679ce9e61a08d42d261ab..293f984861d1c58b824efa003bb99adf7cf7d20d 100644 (file)
--- a/crypto.h
+++ b/crypto.h
@@ -295,6 +295,9 @@ void crypto_adjust_frame_parameters(struct frame *frame,
 /* Maximum length of the nonce used by the PRNG */
 #define NONCE_SECRET_LEN_MAX 64
 
+/** Number of bytes of random to allow before resetting the nonce */
+#define PRNG_NONCE_RESET_BYTES 1024
+
 /**
  * Pseudo-random number generator initialisation.
  * (see \c prng_rand_bytes())