From c5f3979bac1ed6dfd397ac7ada2a9a0dd99f888d Mon Sep 17 00:00:00 2001 From: jow Date: Sat, 9 Jun 2012 13:43:00 +0000 Subject: [PATCH] [packages] openvpn-polarssl: add missing patch from previous commit, remove stray comment git-svn-id: svn://svn.openwrt.org/openwrt/packages@32137 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- net/openvpn-polarssl/Makefile | 1 - .../100-polarssl-havege-rand-compat.patch | 347 ++++++++++++++++++ 2 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 net/openvpn-polarssl/patches/100-polarssl-havege-rand-compat.patch diff --git a/net/openvpn-polarssl/Makefile b/net/openvpn-polarssl/Makefile index ebb95c230..d83f4aa89 100644 --- a/net/openvpn-polarssl/Makefile +++ b/net/openvpn-polarssl/Makefile @@ -7,7 +7,6 @@ include $(TOPDIR)/rules.mk -#http://swupdate.openvpn.org/community/releases/openvpn-2.3-alpha1.tar.gz PKG_NAME:=openvpn-polarssl PKG_VERSION:=2.3-alpha1 PKG_RELEASE=1 diff --git a/net/openvpn-polarssl/patches/100-polarssl-havege-rand-compat.patch b/net/openvpn-polarssl/patches/100-polarssl-havege-rand-compat.patch new file mode 100644 index 000000000..d26821596 --- /dev/null +++ b/net/openvpn-polarssl/patches/100-polarssl-havege-rand-compat.patch @@ -0,0 +1,347 @@ +From 6efeaa2e4462bc10f395d8aceed363c3e77b35a3 Mon Sep 17 00:00:00 2001 +From: Adriaan de Jong +Date: Mon, 2 Apr 2012 09:28:02 +0200 +Subject: [PATCH] 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 +Signed-off-by: Eelse-jan Stutvoet +Acked-by: James Yonan +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 +--- + 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(-) + +--- 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 >= 0x01010000) ++#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 >= 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", 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; + } + +--- 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 >= 0x01010000) ++# 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 1.0, this is the HAVEGE random number generator. ++ * ++ * For PolarSSL 1.1+, this is the CTR_DRBG random number generator. If it ++ * hasn't been initialised yet, the RNG will be initialised using the default ++ * entropy sources. Aside from the default platform entropy sources, an ++ * additional entropy source, the HAVEGE random number generator will also be ++ * added. During initialisation, a personalisation string will be added based ++ * on the time, the PID, and a pointer to the random context. ++ */ ++#if (POLARSSL_VERSION_NUMBER >= 0x01010000) ++ctr_drbg_context * rand_ctx_get(); ++#else ++havege_state * rand_ctx_get(); ++#endif ++ + #endif /* CRYPTO_POLARSSL_H_ */ +--- a/ssl.c ++++ b/ssl.c +@@ -385,6 +385,11 @@ init_ssl (const struct options *options, + tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); + } + ++#ifdef ENABLE_CRYPTO_POLARSSL ++ /* Fox-IT hardening: Personalise the random by mixing in the certificate */ ++ tls_ctx_personalise_random (new_ctx); ++#endif ++ + tls_clear_error (); + return; + +--- a/ssl_backend.h ++++ b/ssl_backend.h +@@ -272,6 +272,16 @@ void tls_ctx_load_extra_certs (struct tl + #endif + ); + ++#ifdef ENABLE_CRYPTO_POLARSSL ++/** ++ * Add a personalisation string to the PolarSSL RNG, based on the certificate ++ * loaded into the given context. ++ * ++ * @param ctx TLS context to use ++ */ ++void tls_ctx_personalise_random(struct tls_root_ctx *ctx); ++#endif ++ + /* ************************************** + * + * Key-state specific functions +--- a/ssl_polarssl.c ++++ b/ssl_polarssl.c +@@ -38,6 +38,9 @@ + #include "manage.h" + #include "ssl_common.h" + ++#include ++#include ++ + #include "ssl_verify_polarssl.h" + #include + +@@ -79,9 +82,6 @@ tls_ctx_server_new(struct tls_root_ctx * + ASSERT(NULL != ctx); + CLEAR(*ctx); + +- ALLOC_OBJ_CLEAR(ctx->hs, havege_state); +- havege_init(ctx->hs); +- + ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context); + ALLOC_OBJ_CLEAR(ctx->priv_key, rsa_context); + +@@ -97,12 +97,8 @@ void + tls_ctx_client_new(struct tls_root_ctx *ctx) + { + ASSERT(NULL != ctx); +- + CLEAR(*ctx); + +- ALLOC_OBJ_CLEAR(ctx->hs, havege_state); +- havege_init(ctx->hs); +- + ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context); + ALLOC_OBJ_CLEAR(ctx->priv_key, rsa_context); + +@@ -137,8 +133,6 @@ tls_ctx_free(struct tls_root_ctx *ctx) + } + #endif + +- free(ctx->hs); +- + if (ctx->allowed_ciphers) + free(ctx->allowed_ciphers); + +@@ -496,6 +490,30 @@ static void my_debug( void *ctx, int lev + } + } + ++/* ++ * Further personalise the RNG using a hash of the public key ++ */ ++void tls_ctx_personalise_random(struct tls_root_ctx *ctx) ++{ ++#if (POLARSSL_VERSION_NUMBER >= 0x01010000) ++ static char old_sha256_hash[32] = {0}; ++ char sha256_hash[32] = {0}; ++ ctr_drbg_context *cd_ctx = rand_ctx_get(); ++ ++ if (NULL != ctx->crt_chain) ++ { ++ x509_cert *cert = ctx->crt_chain; ++ ++ sha2(cert->tbs.p, cert->tbs.len, sha256_hash, false); ++ if ( 0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash))) ++ { ++ ctr_drbg_update(cd_ctx, sha256_hash, 32); ++ memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash)); ++ } ++ } ++#endif /* POLARSSL_VERSION_NUMBER >= 0x01010000 */ ++} ++ + void key_state_ssl_init(struct key_state_ssl *ks_ssl, + const struct tls_root_ctx *ssl_ctx, bool is_server, void *session) + { +@@ -509,7 +527,13 @@ void key_state_ssl_init(struct key_state + /* Initialise SSL context */ + ssl_set_dbg (ks_ssl->ctx, my_debug, NULL); + ssl_set_endpoint (ks_ssl->ctx, ssl_ctx->endpoint); +- ssl_set_rng (ks_ssl->ctx, havege_rand, ssl_ctx->hs); ++ ++#if (POLARSSL_VERSION_NUMBER >= 0x01010000) ++ ssl_set_rng (ks_ssl->ctx, ctr_drbg_random, rand_ctx_get()); ++#else /* POLARSSL_VERSION_NUMBER >= 0x01010000 */ ++ ssl_set_rng (ks_ssl->ctx, havege_rand, rand_ctx_get()); ++#endif /* POLARSSL_VERSION_NUMBER >= 0x01010000 */ ++ + ALLOC_OBJ_CLEAR (ks_ssl->ssn, ssl_session); + ssl_set_session (ks_ssl->ctx, 0, 0, ks_ssl->ssn ); + if (ssl_ctx->allowed_ciphers) +--- a/ssl_polarssl.h ++++ b/ssl_polarssl.h +@@ -30,7 +30,6 @@ + #ifndef SSL_POLARSSL_H_ + #define SSL_POLARSSL_H_ + +-#include + #include + #include "config.h" + +@@ -63,7 +62,6 @@ struct tls_root_ctx { + + int endpoint; /**< Whether or not this is a server or a client */ + +- havege_state *hs; /**< HAVEGE random number state */ + dhm_context *dhm_ctx; /**< Diffie-Helmann-Merkle context */ + x509_cert *crt_chain; /**< Local Certificate chain */ + x509_cert *ca_chain; /**< CA chain for remote verification */