diff --git a/openvpn-fips140-2.3.2.patch b/openvpn-fips140-2.3.2.patch new file mode 100644 index 0000000..777e084 --- /dev/null +++ b/openvpn-fips140-2.3.2.patch @@ -0,0 +1,318 @@ +diff -urNp openvpn-2.3.2.orig/src/openvpn/crypto_backend.h openvpn-2.3.2/src/openvpn/crypto_backend.h +--- openvpn-2.3.2.orig/src/openvpn/crypto_backend.h 2013-08-13 03:24:16.465313821 +0200 ++++ openvpn-2.3.2/src/openvpn/crypto_backend.h 2013-08-13 05:55:40.914256287 +0200 +@@ -452,10 +452,11 @@ void md_ctx_final (md_ctx_t *ctx, uint8_ + * @param key The key to use for the HMAC + * @param key_len The key length to use + * @param kt Static message digest parameters ++ * @param prf_use Intended use for PRF in TLS protocol + * + */ + void hmac_ctx_init (hmac_ctx_t *ctx, const uint8_t *key, int key_length, +- const md_kt_t *kt); ++ const md_kt_t *kt, bool prf_use); + + /* + * Free the given HMAC context. +diff -urNp openvpn-2.3.2.orig/src/openvpn/crypto.c openvpn-2.3.2/src/openvpn/crypto.c +--- openvpn-2.3.2.orig/src/openvpn/crypto.c 2013-08-13 03:24:16.466313824 +0200 ++++ openvpn-2.3.2/src/openvpn/crypto.c 2013-08-13 05:54:09.655008218 +0200 +@@ -486,7 +486,7 @@ init_key_ctx (struct key_ctx *ctx, struc + if (kt->digest && kt->hmac_length > 0) + { + ALLOC_OBJ(ctx->hmac, hmac_ctx_t); +- hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest); ++ hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest, 0); + + msg (D_HANDSHAKE, + "%s: Using %d bit message hash '%s' for HMAC authentication", +@@ -1409,61 +1409,61 @@ free_ssl_lib (void) + #endif /* ENABLE_SSL */ + + /* +- * md5 functions ++ * sha1 functions + */ + + const char * +-md5sum (uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc) ++sha1sum (uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc) + { +- uint8_t digest[MD5_DIGEST_LENGTH]; +- const md_kt_t *md5_kt = md_kt_get("MD5"); ++ uint8_t digest[SHA_DIGEST_LENGTH]; ++ const md_kt_t *sha1_kt = md_kt_get("SHA1"); + +- md_full(md5_kt, buf, len, digest); ++ md_full(sha1_kt, buf, len, digest); + +- return format_hex (digest, MD5_DIGEST_LENGTH, n_print_chars, gc); ++ return format_hex (digest, SHA_DIGEST_LENGTH, n_print_chars, gc); + } + + void +-md5_state_init (struct md5_state *s) ++sha1_state_init (struct sha1_state *s) + { +- const md_kt_t *md5_kt = md_kt_get("MD5"); ++ const md_kt_t *sha1_kt = md_kt_get("SHA1"); + +- md_ctx_init(&s->ctx, md5_kt); ++ md_ctx_init(&s->ctx, sha1_kt); + } + + void +-md5_state_update (struct md5_state *s, void *data, size_t len) ++sha1_state_update (struct sha1_state *s, void *data, size_t len) + { + md_ctx_update(&s->ctx, data, len); + } + + void +-md5_state_final (struct md5_state *s, struct md5_digest *out) ++sha1_state_final (struct sha1_state *s, struct sha1_digest *out) + { + md_ctx_final(&s->ctx, out->digest); + md_ctx_cleanup(&s->ctx); + } + + void +-md5_digest_clear (struct md5_digest *digest) ++sha1_digest_clear (struct sha1_digest *digest) + { + CLEAR (*digest); + } + + bool +-md5_digest_defined (const struct md5_digest *digest) ++sha1_digest_defined (const struct sha1_digest *digest) + { + int i; +- for (i = 0; i < MD5_DIGEST_LENGTH; ++i) ++ for (i = 0; i < SHA_DIGEST_LENGTH; ++i) + if (digest->digest[i]) + return true; + return false; + } + + bool +-md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2) ++sha1_digest_equal (const struct sha1_digest *d1, const struct sha1_digest *d2) + { +- return memcmp(d1->digest, d2->digest, MD5_DIGEST_LENGTH) == 0; ++ return memcmp(d1->digest, d2->digest, SHA_DIGEST_LENGTH) == 0; + } + + #endif /* ENABLE_CRYPTO */ +diff -urNp openvpn-2.3.2.orig/src/openvpn/crypto.h openvpn-2.3.2/src/openvpn/crypto.h +--- openvpn-2.3.2.orig/src/openvpn/crypto.h 2013-08-13 03:24:16.459313788 +0200 ++++ openvpn-2.3.2/src/openvpn/crypto.h 2013-08-13 05:54:09.656008193 +0200 +@@ -364,24 +364,24 @@ void free_ssl_lib (void); + #endif /* ENABLE_SSL */ + + /* +- * md5 functions ++ * sha1 functions + */ + +-struct md5_state { ++struct sha1_state { + md_ctx_t ctx; + }; + +-struct md5_digest { ++struct sha1_digest { + uint8_t digest [MD5_DIGEST_LENGTH]; + }; + +-const char *md5sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc); +-void md5_state_init (struct md5_state *s); +-void md5_state_update (struct md5_state *s, void *data, size_t len); +-void md5_state_final (struct md5_state *s, struct md5_digest *out); +-void md5_digest_clear (struct md5_digest *digest); +-bool md5_digest_defined (const struct md5_digest *digest); +-bool md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2); ++const char *sha1sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc); ++void sha1_state_init (struct sha1_state *s); ++void sha1_state_update (struct sha1_state *s, void *data, size_t len); ++void sha1_state_final (struct sha1_state *s, struct sha1_digest *out); ++void sha1_digest_clear (struct sha1_digest *digest); ++bool sha1_digest_defined (const struct sha1_digest *digest); ++bool sha1_digest_equal (const struct sha1_digest *d1, const struct sha1_digest *d2); + + /* + * Inline functions +diff -urNp openvpn-2.3.2.orig/src/openvpn/crypto_openssl.c openvpn-2.3.2/src/openvpn/crypto_openssl.c +--- openvpn-2.3.2.orig/src/openvpn/crypto_openssl.c 2013-08-13 03:24:16.462313808 +0200 ++++ openvpn-2.3.2/src/openvpn/crypto_openssl.c 2013-08-13 05:56:06.930326789 +0200 +@@ -719,13 +719,17 @@ md_ctx_final (EVP_MD_CTX *ctx, uint8_t * + + void + hmac_ctx_init (HMAC_CTX *ctx, const uint8_t *key, int key_len, +- const EVP_MD *kt) ++ const EVP_MD *kt, bool prf_use) + { + ASSERT(NULL != kt && NULL != ctx); + + CLEAR(*ctx); + + HMAC_CTX_init (ctx); ++ /* FIPS 140-2 explicitly allows MD5 for the use in PRF although it is not ++ * to be used anywhere else */ ++ if(kt == EVP_md5() && prf_use) ++ HMAC_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + HMAC_Init_ex (ctx, key, key_len, kt, NULL); + + /* make sure we used a big enough key */ +diff -urNp openvpn-2.3.2.orig/src/openvpn/crypto_openssl.h openvpn-2.3.2/src/openvpn/crypto_openssl.h +--- openvpn-2.3.2.orig/src/openvpn/crypto_openssl.h 2013-08-13 03:24:16.465313821 +0200 ++++ openvpn-2.3.2/src/openvpn/crypto_openssl.h 2013-08-13 05:54:09.656008193 +0200 +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + /** Generic cipher key type %context. */ + typedef EVP_CIPHER cipher_kt_t; +diff -urNp openvpn-2.3.2.orig/src/openvpn/crypto_polarssl.c openvpn-2.3.2/src/openvpn/crypto_polarssl.c +--- openvpn-2.3.2.orig/src/openvpn/crypto_polarssl.c 2013-08-13 03:24:16.460313793 +0200 ++++ openvpn-2.3.2/src/openvpn/crypto_polarssl.c 2013-08-13 05:56:23.116370864 +0200 +@@ -608,7 +608,7 @@ md_ctx_final (md_context_t *ctx, uint8_t + * TODO: re-enable dmsg for crypto debug + */ + void +-hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info_t *kt) ++hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info_t *kt, bool prf_use) + { + ASSERT(NULL != kt && NULL != ctx); + +diff -urNp openvpn-2.3.2.orig/src/openvpn/init.c openvpn-2.3.2/src/openvpn/init.c +--- openvpn-2.3.2.orig/src/openvpn/init.c 2013-08-13 03:24:16.465313821 +0200 ++++ openvpn-2.3.2/src/openvpn/init.c 2013-08-13 05:54:09.658008149 +0200 +@@ -1352,12 +1352,12 @@ do_route (const struct options *options, + */ + #if P2MP + static void +-save_pulled_options_digest (struct context *c, const struct md5_digest *newdigest) ++save_pulled_options_digest (struct context *c, const struct sha1_digest *newdigest) + { + if (newdigest) + c->c1.pulled_options_digest_save = *newdigest; + else +- md5_digest_clear (&c->c1.pulled_options_digest_save); ++ sha1_digest_clear (&c->c1.pulled_options_digest_save); + } + #endif + +@@ -1649,8 +1649,8 @@ do_up (struct context *c, bool pulled_op + if (!c->c2.did_open_tun + && PULL_DEFINED (&c->options) + && c->c1.tuntap +- && (!md5_digest_defined (&c->c1.pulled_options_digest_save) || !md5_digest_defined (&c->c2.pulled_options_digest) +- || !md5_digest_equal (&c->c1.pulled_options_digest_save, &c->c2.pulled_options_digest))) ++ && (!sha1_digest_defined (&c->c1.pulled_options_digest_save) || !sha1_digest_defined (&c->c2.pulled_options_digest) ++ || !sha1_digest_equal (&c->c1.pulled_options_digest_save, &c->c2.pulled_options_digest))) + { + /* if so, close tun, delete routes, then reinitialize tun and add routes */ + msg (M_INFO, "NOTE: Pulled options changed on restart, will need to close and reopen TUN/TAP device."); +@@ -2697,11 +2697,11 @@ do_compute_occ_strings (struct context * + #ifdef ENABLE_CRYPTO + msg (D_SHOW_OCC_HASH, "Local Options hash (VER=%s): '%s'", + options_string_version (c->c2.options_string_local, &gc), +- md5sum ((uint8_t*)c->c2.options_string_local, ++ sha1sum ((uint8_t*)c->c2.options_string_local, + strlen (c->c2.options_string_local), 9, &gc)); + msg (D_SHOW_OCC_HASH, "Expected Remote Options hash (VER=%s): '%s'", + options_string_version (c->c2.options_string_remote, &gc), +- md5sum ((uint8_t*)c->c2.options_string_remote, ++ sha1sum ((uint8_t*)c->c2.options_string_remote, + strlen (c->c2.options_string_remote), 9, &gc)); + #endif + +diff -urNp openvpn-2.3.2.orig/src/openvpn/ntlm.c openvpn-2.3.2/src/openvpn/ntlm.c +--- openvpn-2.3.2.orig/src/openvpn/ntlm.c 2013-08-13 03:24:16.460313793 +0200 ++++ openvpn-2.3.2/src/openvpn/ntlm.c 2013-08-13 05:54:09.658008149 +0200 +@@ -90,7 +90,7 @@ gen_hmac_md5 (const char* data, int data + hmac_ctx_t hmac_ctx; + CLEAR(hmac_ctx); + +- hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt); ++ hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt, 0); + hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len); + hmac_ctx_final(&hmac_ctx, (unsigned char *)result); + hmac_ctx_cleanup(&hmac_ctx); +diff -urNp openvpn-2.3.2.orig/src/openvpn/openvpn.h openvpn-2.3.2/src/openvpn/openvpn.h +--- openvpn-2.3.2.orig/src/openvpn/openvpn.h 2013-08-13 03:24:16.465313821 +0200 ++++ openvpn-2.3.2/src/openvpn/openvpn.h 2013-08-13 05:54:09.658008149 +0200 +@@ -206,7 +206,7 @@ struct context_1 + #endif + + /* if client mode, hash of option strings we pulled from server */ +- struct md5_digest pulled_options_digest_save; ++ struct sha1_digest pulled_options_digest_save; + /**< Hash of option strings received from the + * remote OpenVPN server. Only used in + * client-mode. */ +@@ -474,9 +474,9 @@ struct context_2 + bool did_pre_pull_restore; + + /* hash of pulled options, so we can compare when options change */ +- bool pulled_options_md5_init_done; +- struct md5_state pulled_options_state; +- struct md5_digest pulled_options_digest; ++ bool pulled_options_sha1_init_done; ++ struct sha1_state pulled_options_state; ++ struct sha1_digest pulled_options_digest; + + struct event_timeout server_poll_interval; + +diff -urNp openvpn-2.3.2.orig/src/openvpn/push.c openvpn-2.3.2/src/openvpn/push.c +--- openvpn-2.3.2.orig/src/openvpn/push.c 2013-08-13 03:24:16.459313788 +0200 ++++ openvpn-2.3.2/src/openvpn/push.c 2013-08-13 05:54:09.659008129 +0200 +@@ -446,10 +446,10 @@ process_incoming_push_msg (struct contex + if (ch == ',') + { + struct buffer buf_orig = buf; +- if (!c->c2.pulled_options_md5_init_done) ++ if (!c->c2.pulled_options_sha1_init_done) + { +- md5_state_init (&c->c2.pulled_options_state); +- c->c2.pulled_options_md5_init_done = true; ++ sha1_state_init (&c->c2.pulled_options_state); ++ c->c2.pulled_options_sha1_init_done = true; + } + if (!c->c2.did_pre_pull_restore) + { +@@ -465,13 +465,13 @@ process_incoming_push_msg (struct contex + { + case 0: + case 1: +- md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig)); +- md5_state_final (&c->c2.pulled_options_state, &c->c2.pulled_options_digest); +- c->c2.pulled_options_md5_init_done = false; ++ sha1_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig)); ++ sha1_state_final (&c->c2.pulled_options_state, &c->c2.pulled_options_digest); ++ c->c2.pulled_options_sha1_init_done = false; + ret = PUSH_MSG_REPLY; + break; + case 2: +- md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig)); ++ sha1_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig)); + ret = PUSH_MSG_CONTINUATION; + break; + } +diff -urNp openvpn-2.3.2.orig/src/openvpn/ssl.c openvpn-2.3.2/src/openvpn/ssl.c +--- openvpn-2.3.2.orig/src/openvpn/ssl.c 2013-08-13 03:24:16.459313788 +0200 ++++ openvpn-2.3.2/src/openvpn/ssl.c 2013-08-13 05:54:09.660008110 +0200 +@@ -1342,8 +1342,8 @@ tls1_P_hash(const md_kt_t *md_kt, + chunk = md_kt_size(md_kt); + A1_len = md_kt_size(md_kt); + +- hmac_ctx_init(&ctx, sec, sec_len, md_kt); +- hmac_ctx_init(&ctx_tmp, sec, sec_len, md_kt); ++ hmac_ctx_init(&ctx, sec, sec_len, md_kt, 1); ++ hmac_ctx_init(&ctx_tmp, sec, sec_len, md_kt, 1); + + hmac_ctx_update(&ctx,seed,seed_len); + hmac_ctx_final(&ctx, A1); diff --git a/openvpn.changes b/openvpn.changes index 87db9ac..08512b6 100644 --- a/openvpn.changes +++ b/openvpn.changes @@ -4,6 +4,13 @@ Tue Jan 14 10:43:19 UTC 2014 - mt@suse.de - Updated README.SUSE, documented also the rcopenvpn compatibility wrapper script (bnc#848070). +------------------------------------------------------------------- +Thu Jan 9 14:14:19 UTC 2014 - meissner@suse.com + +- openvpn-fips140-2.3.2.patch: Allow usage of SHA1 instead of MD5 in + some internal checking routines. This allows operation in FIPS 140-2 + mode. + ------------------------------------------------------------------- Tue Dec 17 15:26:16 UTC 2013 - mt@suse.de diff --git a/openvpn.spec b/openvpn.spec index 921e653..af5344c 100644 --- a/openvpn.spec +++ b/openvpn.spec @@ -48,6 +48,7 @@ Source10: %{name}-tmpfile.conf Source11: rc%{name} Patch1: %{name}-2.3-plugin-man.dif Patch5: %{name}-2.3.0-man-dot.diff +Patch6: %{name}-fips140-2.3.2.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: gpg-offline BuildRequires: iproute2 @@ -124,6 +125,7 @@ chroot directives. %setup -q -n %{name}-%{version} %patch1 -p0 %patch5 -p0 +%patch6 -p1 sed -e "s|\" __DATE__|$(date '+%b %e %Y' -r version.m4)\"|g" -i src/openvpn/options.c # %%doc items shouldn't be executable.