Merge ~j-latten/ubuntu/+source/openvpn:disco-openvpn-fips-crash-1807439 into ubuntu/+source/openvpn:ubuntu/devel

Proposed by Joy Latten
Status: Merged
Approved by: Andreas Hasenack
Approved revision: b2baff9479374293e4f6a4e138d15da60137dec7
Merged at revision: b2baff9479374293e4f6a4e138d15da60137dec7
Proposed branch: ~j-latten/ubuntu/+source/openvpn:disco-openvpn-fips-crash-1807439
Merge into: ubuntu/+source/openvpn:ubuntu/devel
Diff against target: 132 lines (+110/-0)
3 files modified
debian/changelog (+7/-0)
debian/patches/openvpn-fips-2.4.patch (+102/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
Andreas Hasenack Approve
Seth Arnold (community) Approve
Canonical Server Pending
Review via email: mp+361583@code.launchpad.net

Description of the change

LP #1807439
openvpn when establishing a tls connection will segfault when used with Ubuntu's FIPS 140-2 libcrypto.so (openssl).

openvpn tls connection does TLS PRF(pseudorandom function) to produce securely generated pseudo random output that is used to generate keys.
MD5 is used as the hash in this computation.

FIPS 140-2 does not permit MD5 use except when used for pseudorandom function (PRF). When openvpn requests MD5 operation to FIPS-mode libcrypto.so, since it is not allowed in general, FIPS-mode libcrypto.so goes into an error state.

openvpn needs to set and pass a flag that FIPS-mode libcrypto.so recognizes and that indicates it is using MD5 for PRF, thereby FIPS-mode libcrypto.so will grant the request instead of entering an error state. In non-FIPS libcrypto.so the flag has no meaning.

To post a comment you must log in.
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Thanks for this! First pass, comments inline.

review: Needs Fixing
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Requesting a review from the security team, given that this patch has not yet made it into openvpn upstream.

Revision history for this message
Seth Arnold (seth-arnold) wrote :

The general outline of it looks good to me.

Thanks

review: Approve
Revision history for this message
Joy Latten (j-latten) wrote :
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Looks good, thanks. +1

review: Approve
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I'll sponsor this.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 1b1e956..027ec52 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,10 @@
6+openvpn (2.4.6-1ubuntu3) disco; urgency=medium
7+
8+ * d/p/openvpn-fips-2.4.patch: Allow MD5 in FIPS mode (openssl) for PRF.
9+ (LP: #1807439)
10+
11+ -- Joy Latten <joy.latten@canonical.com> Wed, 09 Jan 2019 12:25:59 -0600
12+
13 openvpn (2.4.6-1ubuntu2) cosmic; urgency=medium
14
15 * d/openvpn@.service: Add CAP_AUDIT_WRITE to avoid issues with callout
16diff --git a/debian/patches/openvpn-fips-2.4.patch b/debian/patches/openvpn-fips-2.4.patch
17new file mode 100644
18index 0000000..4d2221d
19--- /dev/null
20+++ b/debian/patches/openvpn-fips-2.4.patch
21@@ -0,0 +1,102 @@
22+Description: Use openssl FIPS flag to indicate MD5 use for PRF.
23+ MD5 is not allowed in FIPS 140-2 except for PRF. OpenVPN needs
24+ to send EVP_MD_CTX_FLAG_NON_FIPS_ALLOW flag to FIPS mode openssl
25+ for PRF to indicate the exception.
26+Bug: https://community.openvpn.net/openvpn/ticket/725
27+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1807439
28+Author: Stephan Mueller <stephan.mueller@atsec.com>
29+
30+diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
31+index 03e880e..25e8fc4 100644
32+--- a/src/openvpn/crypto.c
33++++ b/src/openvpn/crypto.c
34+@@ -876,7 +876,7 @@ init_key_ctx(struct key_ctx *ctx, struct key *key,
35+ if (kt->digest && kt->hmac_length > 0)
36+ {
37+ ctx->hmac = hmac_ctx_new();
38+- hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_length, kt->digest);
39++ hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_length, kt->digest, 0);
40+
41+ msg(D_HANDSHAKE,
42+ "%s: Using %d bit message hash '%s' for HMAC authentication",
43+diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
44+index b7f519b..8662600 100644
45+--- a/src/openvpn/crypto_backend.h
46++++ b/src/openvpn/crypto_backend.h
47+@@ -604,10 +604,11 @@ void hmac_ctx_free(hmac_ctx_t *ctx);
48+ * @param key The key to use for the HMAC
49+ * @param key_len The key length to use
50+ * @param kt Static message digest parameters
51++ * @param prf_use Intended use for PRF in TLS protocol
52+ *
53+ */
54+ void hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, int key_length,
55+- const md_kt_t *kt);
56++ const md_kt_t *kt, bool prf_use);
57+
58+ /*
59+ * Free the given HMAC context.
60+diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c
61+index 0cb7f81..d7f931d 100644
62+--- a/src/openvpn/crypto_mbedtls.c
63++++ b/src/openvpn/crypto_mbedtls.c
64+@@ -857,7 +857,7 @@ hmac_ctx_free(mbedtls_md_context_t *ctx)
65+
66+ void
67+ hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, int key_len,
68+- const mbedtls_md_info_t *kt)
69++ const mbedtls_md_info_t *kt, bool prf_use)
70+ {
71+ ASSERT(NULL != kt && NULL != ctx);
72+
73+diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
74+index 9e8d3f3..d5302ae 100644
75+--- a/src/openvpn/crypto_openssl.c
76++++ b/src/openvpn/crypto_openssl.c
77+@@ -926,11 +926,17 @@ hmac_ctx_free(HMAC_CTX *ctx)
78+
79+ void
80+ hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len,
81+- const EVP_MD *kt)
82++ const EVP_MD *kt, bool prf_use)
83+ {
84+ ASSERT(NULL != kt && NULL != ctx);
85+
86+ HMAC_CTX_reset(ctx);
87++
88++ /* FIPS 140-2 explicitly allows MD5 for the use in PRF although it is not
89++ * to be used anywhere else */
90++ if(kt == EVP_md5() && prf_use)
91++ HMAC_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
92++
93+ HMAC_Init_ex(ctx, key, key_len, kt, NULL);
94+
95+ /* make sure we used a big enough key */
96+diff --git a/src/openvpn/ntlm.c b/src/openvpn/ntlm.c
97+index 077fa3e..83585e2 100644
98+--- a/src/openvpn/ntlm.c
99++++ b/src/openvpn/ntlm.c
100+@@ -88,7 +88,7 @@ gen_hmac_md5(const uint8_t *data, int data_len, const uint8_t *key, int key_len,
101+ const md_kt_t *md5_kt = md_kt_get("MD5");
102+ hmac_ctx_t *hmac_ctx = hmac_ctx_new();
103+
104+- hmac_ctx_init(hmac_ctx, key, key_len, md5_kt);
105++ hmac_ctx_init(hmac_ctx, key, key_len, md5_kt, 0);
106+ hmac_ctx_update(hmac_ctx, data, data_len);
107+ hmac_ctx_final(hmac_ctx, result);
108+ hmac_ctx_cleanup(hmac_ctx);
109+diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
110+index c0e1dd6..f929237 100644
111+--- a/src/openvpn/ssl.c
112++++ b/src/openvpn/ssl.c
113+@@ -1637,8 +1637,8 @@ tls1_P_hash(const md_kt_t *md_kt,
114+ chunk = md_kt_size(md_kt);
115+ A1_len = md_kt_size(md_kt);
116+
117+- hmac_ctx_init(ctx, sec, sec_len, md_kt);
118+- hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt);
119++ hmac_ctx_init(ctx, sec, sec_len, md_kt, 1);
120++ hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt, 1);
121+
122+ hmac_ctx_update(ctx,seed,seed_len);
123+ hmac_ctx_final(ctx, A1);
124diff --git a/debian/patches/series b/debian/patches/series
125index a903d3d..cc99ac9 100644
126--- a/debian/patches/series
127+++ b/debian/patches/series
128@@ -6,3 +6,4 @@ kfreebsd_support.patch
129 match-manpage-and-command-help.patch
130 spelling_errors.patch
131 systemd.patch
132+openvpn-fips-2.4.patch

Subscribers

People subscribed via source and target branches