summaryrefslogtreecommitdiffstats
path: root/src/openvpn/crypto_polarssl.c
diff options
context:
space:
mode:
authorAdriaan de Jong <dejong@fox-it.com>2012-04-02 09:28:02 +0200
committerDavid Sommerseth <davids@redhat.com>2012-04-27 23:31:44 +0200
commit6efeaa2e4462bc10f395d8aceed363c3e77b35a3 (patch)
tree48732b5de9c86e8989dfeca0756b4162a3072088 /src/openvpn/crypto_polarssl.c
parent4e846b39a35b5f9501e4283be0af620d7c9c8b5c (diff)
downloadopenvpn-6efeaa2e4462bc10f395d8aceed363c3e77b35a3.tar.gz
openvpn-6efeaa2e4462bc10f395d8aceed363c3e77b35a3.tar.xz
openvpn-6efeaa2e4462bc10f395d8aceed363c3e77b35a3.zip
Added support for new PolarSSL 1.1 RNG
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 <dejong@fox-it.com> Signed-off-by: Eelse-jan Stutvoet <stutvoet@fox-it.com> Acked-by: James Yonan <james@openvpn.net> Message-Id: 1333351687-3732-1-git-send-email-dejong@fox-it.com URL: http://article.gmane.org/gmane.network.openvpn.devel/6210 Signed-off-by: David Sommerseth <davids@redhat.com>
Notes
Notes: This patch was ACKed by James Yonan in an IRC meeting March 29, 2012 under the condition that PolarSSL 1.0 and havege support is removed later on. Currently, the meeting minutes have not been made public. (David Sommerseth, Fri Apr 27 21:31:03 UTC 2012)
Diffstat (limited to 'src/openvpn/crypto_polarssl.c')
-rw-r--r--src/openvpn/crypto_polarssl.c84
1 files changed, 74 insertions, 10 deletions
diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c
index 0e6728c..158ccfc 100644
--- a/src/openvpn/crypto_polarssl.c
+++ b/src/openvpn/crypto_polarssl.c
@@ -42,12 +42,18 @@
#include "buffer.h"
#include "integer.h"
#include "crypto_backend.h"
+#include "otime.h"
+#include "misc.h"
#include <polarssl/des.h>
#include <polarssl/md5.h>
#include <polarssl/cipher.h>
#include <polarssl/havege.h>
+#if (POLARSSL_VERSION_NUMBER >= 0x01010000)
+#include <polarssl/entropy.h>
+#endif
+
/*
*
* Hardware engine support. Allows loading/unloading of engines.
@@ -149,7 +155,6 @@ show_available_engines ()
"available\n");
}
-
/*
*
* Random number functions, used in cases where we want
@@ -159,29 +164,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 >= 0x01010000)
+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, &gc);
+
+ /*
+ * 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(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc));
+
+ /* Initialise PolarSSL RNG, and built-in entropy sources */
+ entropy_init(&ec);
+
+ if (0 != ctr_drbg_init(&cd_ctx, entropy_func, &ec, BPTR(&pers_string), BLEN(&pers_string)))
+ msg (M_FATAL, "Failed to initialize random generator");
+
+ gc_free(&gc);
+ rand_initialised = true;
+ }
+
+ return &cd_ctx;
+}
+
+#else /* (POLARSSL_VERSION_NUMBER < 0x01010000) */
+
+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);
- hs_initialised = true;
+ rand_initialised = true;
}
+ return &hs;
+}
+
+#endif /* (POLARSSL_VERSION_NUMBER >= 0x01010000) */
+
+int
+rand_bytes (uint8_t *output, int len)
+{
+#if (POLARSSL_VERSION_NUMBER >= 0x01010000)
+ ctr_drbg_context *rng_ctx = rand_ctx_get();
+#else /* (POLARSSL_VERSION_NUMBER >= 0x01010000) */
+ havege_state *rng_ctx = rand_ctx_get();
+#endif /* (POLARSSL_VERSION_NUMBER >= 0x01010000) */
+
while (len > 0)
{
- const int blen = min_int (len, int_size);
- const int rand_int = havege_rand(&hs);
-
+#if (POLARSSL_VERSION_NUMBER >= 0x01010000)
+ 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 >= 0x01010000) */
+ const size_t blen = min_int (len, sizeof(int));
+ const int rand_int = havege_rand(rng_ctx);
memcpy (output, &rand_int, blen);
+
+#endif /* (POLARSSL_VERSION_NUMBER >= 0x01010000) */
+
output += blen;
len -= blen;
}
+
return 1;
}