Re: [Openvpn-devel] [PATCH 1/2] Added support for new PolarSSL 1.1 RNG

2012-02-28 Thread Fabian Knittel
Hi Adriaan,

I only found a minor nit:

2012/2/28 Adriaan de Jong :
> --- a/ssl.c
> +++ b/ssl.c
> @@ -385,6 +385,11 @@ init_ssl (const struct options *options, struct 
> tls_root_ctx *new_ctx)
>       tls_ctx_restrict_ciphers(new_ctx, options->cipher_list);
>     }
>
> +#ifdef USE_POLARSSL
> +  /* Fox-IT hardening: Personalise the random by mixing in the certificate */
> +  tls_ctx_personalise_random (new_ctx);
> +#endif

Unless it's intentional, the "Fox-IT hardening" string is probably
from an earlier, internal iteration?

The rest looks fine AFAICT. :)

Cheers
Fabian



[Openvpn-devel] [PATCH 1/2] Added support for new PolarSSL 1.1 RNG

2012-02-28 Thread Adriaan de Jong
This patch, while retaining PolarSSL 1.0 support, introduces the PolarSSL 1.1 
DRBG. This RNG adds a number of features, including support for personalisation 
strings and multiple entropy sources.

Personalisation strings have been implemented, based on PID, program name, 
place within memory, and a hash of the user's certificate.

The entropy sources used are the platform default ones. Which ones these are 
depends on how PolarSSL was built, but usually this includes:

 - /dev/urandom or the Windows CryptoAPI RNG
 - the HAVEGE RNG
 - the output of PolarSSL's hardclock() call (usually RDTSC)

Finally, this patch moves to only one instance of the RNG  per OpenVPN 
instance, instead of one per keystate

Signed-off-by: Adriaan de Jong 
Signed-off-by: Eelse-jan Stutvoet 
---
 crypto_polarssl.c |   84 ++--
 crypto_polarssl.h |   25 
 ssl.c |5 +++
 ssl_backend.h |   10 ++
 ssl_polarssl.c|   44 +--
 ssl_polarssl.h|2 -
 6 files changed, 148 insertions(+), 22 deletions(-)

diff --git a/crypto_polarssl.c b/crypto_polarssl.c
index e7470d5..8eb47db 100644
--- a/crypto_polarssl.c
+++ b/crypto_polarssl.c
@@ -36,12 +36,18 @@
 #include "buffer.h"
 #include "integer.h"
 #include "crypto_backend.h"
+#include "otime.h"
+#include "misc.h"

 #include 
 #include 
 #include 
 #include 

+#if (POLARSSL_VERSION_NUMBER >= 0x0101)
+#include 
+#endif
+
 /*
  *
  * Hardware engine support. Allows loading/unloading of engines.
@@ -143,7 +149,6 @@ show_available_engines ()
   "available\n");
 }

-
 /*
  *
  * Random number functions, used in cases where we want
@@ -153,29 +158,88 @@ show_available_engines ()
  *
  */

-int
-rand_bytes (uint8_t *output, int len)
+/*
+ * Initialise the given ctr_drbg context, using a personalisation string and an
+ * entropy gathering function.
+ */
+#if (POLARSSL_VERSION_NUMBER >= 0x0101)
+ctr_drbg_context * rand_ctx_get()
+{
+  static entropy_context ec = {0};
+  static ctr_drbg_context cd_ctx = {0};
+  static bool rand_initialised = false;
+
+  if (!rand_initialised)
+{
+  struct gc_arena gc = gc_new();
+  struct buffer pers_string = alloc_buf_gc(100, );
+
+  /*
+   * Personalisation string, should be as unique as possible (see NIST
+   * 800-90 section 8.7.1). We have very little information at this stage.
+   * Include Program Name, memory address of the context and PID.
+   */
+  buf_printf(_string, "OpenVPN %0u %p %s", openvpn_getpid(), _ctx, 
time_string(0, 0, 0, ));
+
+  /* Initialise PolarSSL RNG, and built-in entropy sources */
+  entropy_init();
+
+  if (0 != ctr_drbg_init(_ctx, entropy_func, , BPTR(_string), 
BLEN(_string)))
+msg (M_FATAL, "Failed to initialize random generator");
+
+  gc_free();
+  rand_initialised = true;
+  }
+
+  return _ctx;
+}
+
+#else /* (POLARSSL_VERSION_NUMBER < 0x0101) */
+
+havege_state * rand_ctx_get()
 {
   static havege_state hs = {0};
-  static bool hs_initialised = false;
-  const int int_size = sizeof(int);
+  static bool rand_initialised = false;

-  if (!hs_initialised)
+  if (!rand_initialised)
 {
   /* Initialise PolarSSL RNG */
   havege_init();
-  hs_initialised = true;
+  rand_initialised = true;
 }

+  return 
+}
+
+#endif /* (POLARSSL_VERSION_NUMBER >= 0x0101) */
+
+int
+rand_bytes (uint8_t *output, int len)
+{
+#if (POLARSSL_VERSION_NUMBER >= 0x0101)
+  ctr_drbg_context *rng_ctx = rand_ctx_get();
+#else /* (POLARSSL_VERSION_NUMBER >= 0x0101) */
+  havege_state *rng_ctx = rand_ctx_get();
+#endif /* (POLARSSL_VERSION_NUMBER >= 0x0101) */
+
   while (len > 0)
 {
-  const int blen   = min_int (len, int_size);
-  const int rand_int   = havege_rand();
-
+#if (POLARSSL_VERSION_NUMBER >= 0x0101)
+  const size_t blen = min_int (len, CTR_DRBG_MAX_REQUEST);
+  if (0 != ctr_drbg_random(rng_ctx, output, blen))
+   return 0;
+
+#else /* (POLARSSL_VERSION_NUMBER >= 0x0101) */
+  const size_t blen = min_int (len, sizeof(int));
+  const int rand_int = havege_rand(rng_ctx);
   memcpy (output, _int, blen);
+
+#endif /* (POLARSSL_VERSION_NUMBER >= 0x0101) */
+
   output += blen;
   len -= blen;
 }
+
   return 1;
 }

diff --git a/crypto_polarssl.h b/crypto_polarssl.h
index 358483a..2f303db 100644
--- a/crypto_polarssl.h
+++ b/crypto_polarssl.h
@@ -30,9 +30,16 @@
 #ifndef CRYPTO_POLARSSL_H_
 #define CRYPTO_POLARSSL_H_

+#include 
 #include 
 #include 

+#if (POLARSSL_VERSION_NUMBER >= 0x0101)
+#  include 
+#else
+#  include 
+#endif
+
 /** Generic cipher key type %context. */
 typedef cipher_info_t cipher_kt_t;

@@ -71,4 +78,22 @@ typedef md_context_t hmac_ctx_t;
 #define SHA_DIGEST_LENGTH  20
 #define DES_KEY_LENGTH 8

+/**
+ * Returns a singleton instance of the PolarSSL random number generator.
+ *
+ * For PolarSSL