summaryrefslogtreecommitdiff
path: root/openvpn/src/openvpn/crypto_polarssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'openvpn/src/openvpn/crypto_polarssl.c')
-rw-r--r--openvpn/src/openvpn/crypto_polarssl.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/openvpn/src/openvpn/crypto_polarssl.c b/openvpn/src/openvpn/crypto_polarssl.c
index 0e6728c8..3978a3c6 100644
--- a/openvpn/src/openvpn/crypto_polarssl.c
+++ b/openvpn/src/openvpn/crypto_polarssl.c
@@ -42,12 +42,16 @@
#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>
+#include <polarssl/entropy.h>
+
/*
*
* Hardware engine support. Allows loading/unloading of engines.
@@ -149,7 +153,6 @@ show_available_engines ()
"available\n");
}
-
/*
*
* Random number functions, used in cases where we want
@@ -159,29 +162,65 @@ 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.
+ */
+ctr_drbg_context * rand_ctx_get()
{
- static havege_state hs = {0};
- static bool hs_initialised = false;
- const int int_size = sizeof(int);
+ static entropy_context ec = {0};
+ static ctr_drbg_context cd_ctx = {0};
+ static bool rand_initialised = false;
- if (!hs_initialised)
+ if (!rand_initialised)
{
- /* Initialise PolarSSL RNG */
- havege_init(&hs);
- hs_initialised = true;
- }
+ 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;
+}
+
+#ifdef ENABLE_PREDICTION_RESISTANCE
+void rand_ctx_enable_prediction_resistance()
+{
+ ctr_drbg_context *cd_ctx = rand_ctx_get();
+
+ ctr_drbg_set_prediction_resistance(cd_ctx, 1);
+}
+#endif /* ENABLE_PREDICTION_RESISTANCE */
+
+int
+rand_bytes (uint8_t *output, int len)
+{
+ ctr_drbg_context *rng_ctx = rand_ctx_get();
while (len > 0)
{
- const int blen = min_int (len, int_size);
- const int rand_int = havege_rand(&hs);
+ const size_t blen = min_int (len, CTR_DRBG_MAX_REQUEST);
+ if (0 != ctr_drbg_random(rng_ctx, output, blen))
+ return 0;
- memcpy (output, &rand_int, blen);
output += blen;
len -= blen;
}
+
return 1;
}