Browse code

tls-crypt-v2: add specification to doc/

This is a preliminary description of tls-crypt-v2. It should give a good
impression about the reasoning and design behind tls-crypt-v2, but might
need some polishing and updating.

Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <1540208715-14044-1-git-send-email-steffan.karger@fox-it.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17788.html
Signed-off-by: David Sommerseth <davids@openvpn.net>

Steffan Karger authored on 2018/10/22 20:45:10
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,189 @@
0
+Client-specific tls-crypt keys (--tls-crypt-v2)
1
+===============================================
2
+
3
+This document describes the ``--tls-crypt-v2`` option, which enables OpenVPN
4
+to use client-specific ``--tls-crypt`` keys.
5
+
6
+Rationale
7
+---------
8
+
9
+``--tls-auth`` and ``tls-crypt`` use a pre-shared group key, which is shared
10
+among all clients and servers in an OpenVPN deployment.  If any client or
11
+server is compromised, the attacker will have access to this shared key, and it
12
+will no longer provide any security.  To reduce the risk of losing pre-shared
13
+keys, ``tls-crypt-v2`` adds the ability to supply each client with a unique
14
+tls-crypt key.  This allows large organisations and VPN providers to profit
15
+from the same DoS and TLS stack protection that small deployments can already
16
+achieve using ``tls-auth`` or ``tls-crypt``.
17
+
18
+Also, for ``tls-crypt``, even if all these peers succeed in keeping the key
19
+secret, the key lifetime is limited to roughly 8000 years, divided by the
20
+number of clients (see the ``--tls-crypt`` section of the man page).  Using
21
+client-specific keys, we lift this lifetime requirement to roughly 8000 years
22
+for each client key (which "Should Be Enough For Everybody (tm)").
23
+
24
+
25
+Introduction
26
+------------
27
+
28
+``tls-crypt-v2`` uses an encrypted cookie mechanism to introduce
29
+client-specific tls-crypt keys without introducing a lot of server-side state.
30
+The client-specific key is encrypted using a server key.  The server key is the
31
+same for all servers in a group.  When a client connects, it first sends the
32
+encrypted key to the server, such that the server can decrypt the key and all
33
+messages can thereafter be encrypted using the client-specific key.
34
+
35
+A wrapped (encrypted and authenticated) client-specific key can also contain
36
+metadata.  The metadata is wrapped together with the key, and can be used to
37
+allow servers to identify clients and/or key validity.  This allows the server
38
+to abort the connection immediately after receiving the first packet, rather
39
+than performing an entire TLS handshake.  Aborting the connection this early
40
+greatly improves the DoS resilience and reduces attack surface against
41
+malicious clients that have the ``tls-crypt`` or ``tls-auth`` key.  This is
42
+particularly relevant for large deployments (think lost key or disgruntled
43
+employee) and VPN providers (clients are not trusted).
44
+
45
+To allow for a smooth transition, ``tls-crypt-v2`` is designed such that a
46
+server can enable both ``tls-crypt-v2`` and either ``tls-crypt`` or
47
+``tls-auth``.  This is achieved by introducing a P_CONTROL_HARD_RESET_CLIENT_V3
48
+opcode, that indicates that the client wants to use ``tls-crypt-v2`` for the
49
+current connection.
50
+
51
+For an exact specification and more details, read the Implementation section.
52
+
53
+
54
+Implementation
55
+--------------
56
+
57
+When setting up a tls-crypt-v2 group (similar to generating a tls-crypt or
58
+tls-auth key previously):
59
+
60
+1. Generate a tls-crypt-v2 server key using OpenVPN's ``--tls-crypt-v2-genkey server``.
61
+   This key contains 2 512-bit keys, of which we use:
62
+
63
+   * the first 256 bits of key 1 as AES-256-CTR encryption key ``Ke``
64
+   * the first 256 bits of key 2 as HMAC-SHA-256 authentication key ``Ka``
65
+
66
+   This format is similar to the format for regular ``tls-crypt``/``tls-auth``
67
+   and data channel keys, which allows us to reuse code.
68
+
69
+2. Add the tls-crypt-v2 server key to all server configs
70
+   (``tls-crypt-v2 /path/to/server.key``)
71
+
72
+
73
+When provisioning a client, create a client-specific tls-crypt key:
74
+
75
+1. Generate 2048 bits client-specific key ``Kc`` using OpenVPN's ``--tls-crypt-v2-genkey client``
76
+
77
+2. Optionally generate metadata
78
+
79
+   The first byte of the metadata determines the type.  The initial
80
+   implementation supports the following types:
81
+
82
+   0x00 (USER):         User-defined free-form data.
83
+   0x01 (TIMESTAMP):    64-bit network order unix timestamp of key generation.
84
+
85
+   The timestamp can be used to reject too-old tls-crypt-v2 client keys.
86
+
87
+   User metadata could for example contain the users certificate serial, such
88
+   that the incoming connection can be verified against a CRL.
89
+
90
+   If no metadata is supplied during key generation, openvpn defaults to the
91
+   TIMESTAMP metadata type.
92
+
93
+3. Create a wrapped client key ``WKc``, using the same nonce-misuse-resistant
94
+   SIV construction we use for tls-crypt:
95
+
96
+   ``len = len(WKc)`` (16 bit, network byte order)
97
+
98
+   ``T = HMAC-SHA256(Ka, len || Kc || metadata)``
99
+
100
+   ``IV = 128 most significant bits of T``
101
+
102
+   ``WKc = T || AES-256-CTR(Ke, IV, Kc || metadata) || len``
103
+
104
+   Note that the length of ``WKc`` can be computed before composing ``WKc``,
105
+   because the length of each component is known (and AES-256-CTR does not add
106
+   any padding).
107
+
108
+4. Create a tls-crypt-v2 client key: PEM-encode ``Kc || WKc`` and store in a
109
+   file, using the header ``-----BEGIN OpenVPN tls-crypt-v2 client key-----``
110
+   and the footer ``-----END OpenVPN tls-crypt-v2 client key-----``.  (The PEM
111
+   format is simple, and following PEM allows us to use the crypto lib function
112
+   for en/decoding.)
113
+
114
+5. Add the tls-crypt-v2 client key to the client config
115
+   (``tls-crypt-v2 /path/to/client-specific.key``)
116
+
117
+
118
+When setting up the openvpn connection:
119
+
120
+1. The client reads the tls-crypt-v2 key from its config, and:
121
+
122
+   1. loads ``Kc`` as its tls-crypt key,
123
+   2. stores ``WKc`` in memory for sending to the server.
124
+
125
+2. To start the connection, the client creates a P_CONTROL_HARD_RESET_CLIENT_V3
126
+   message, wraps it with tls-crypt using ``Kc`` as the key, and appends
127
+   ``WKc``.  (``WKc`` must not be encrypted, to prevent a chicken-and-egg
128
+   problem.)
129
+
130
+3. The server receives the P_CONTROL_HARD_RESET_CLIENT_V3 message, and
131
+
132
+   1. reads the WKc length field from the end of the message, and extracts WKc
133
+      from the message
134
+   2. unwraps ``WKc``
135
+   3. uses unwrapped ``Kc`` to verify the remaining
136
+      P_CONTROL_HARD_RESET_CLIENT_V3 message's (encryption and) authentication.
137
+
138
+   The message is dropped and no error response is sent when either 3.1, 3.2 or
139
+   3.3 fails (DoS protection).
140
+
141
+4. Server optionally checks metadata using a --tls-crypt-v2-verify script
142
+
143
+   This allows early abort of connection, *before* we expose any of the
144
+   notoriously dangerous TLS, X.509 and ASN.1 parsers and thereby reduces the
145
+   attack surface of the server.
146
+
147
+   The metadata is checked *after* the OpenVPN three-way handshake has
148
+   completed, to prevent DoS attacks.  (That is, once the client has proved to
149
+   the server that it possesses Kc, by authenticating a packet that contains the
150
+   session ID picked by the server.)
151
+
152
+   A server should not send back any error messages if metadata verification
153
+   fails, to reduce attack surface and maximize DoS resilience.
154
+
155
+6. Client and server use ``Kc`` for (un)wrapping any following control channel
156
+   messages.
157
+
158
+
159
+Considerations
160
+--------------
161
+
162
+To allow for a smooth transition, the server implementation allows
163
+``tls-crypt`` or ``tls-auth`` to be used simultaneously with ``tls-crypt-v2``.
164
+This specification does not allow simultaneously using ``tls-crypt-v2`` and
165
+connections without any control channel wrapping, because that would break DoS
166
+resilience.
167
+
168
+WKc includes a length field, so we leave the option for future extension of the
169
+P_CONTROL_HEAD_RESET_CLIENT_V3 message open.  (E.g. add payload to the reset to
170
+indicate low-level protocol features.)
171
+
172
+``tls-crypt-v2`` uses fixed crypto algorithms, because:
173
+
174
+ * The crypto is used before we can do any negotiation, so the algorithms have
175
+   to be predefined.
176
+ * The crypto primitives are chosen conservatively, making problems with these
177
+   primitives unlikely.
178
+ * Making anything configurable adds complexity, both in implementation and
179
+   usage.  We should not add any more complexity than is absolutely necessary.
180
+
181
+Potential ``tls-crypt-v2`` risks:
182
+
183
+ * Slightly more work on first connection (``WKc`` unwrap + hard reset unwrap)
184
+   than with ``tls-crypt`` (hard reset unwrap) or ``tls-auth`` (hard reset auth).
185
+ * Flexible metadata allow mistakes
186
+   (So we should make it easy to do it right.  Provide tooling to create client
187
+   keys based on cert serial + CA fingerprint, provide script that uses CRL (if
188
+   available) to drop revoked keys.)