diff options
author | Adriaan de Jong <dejong@fox-it.com> | 2012-04-02 09:28:02 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2012-04-27 23:31:44 +0200 |
commit | 6efeaa2e4462bc10f395d8aceed363c3e77b35a3 (patch) | |
tree | 48732b5de9c86e8989dfeca0756b4162a3072088 /src/openvpn/crypto_polarssl.c | |
parent | 4e846b39a35b5f9501e4283be0af620d7c9c8b5c (diff) | |
download | openvpn-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.c | 84 |
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; } |