Hi,

As mentioned previously on hackathons, IRC and the mailing list, we've
been working on tls-crypt (which is available in 2.4) and a variant that
requires a bit more provisioning, but is better suited for large VPN
setups and also useful for VPN providers: tls-crypt-v2.  This is a
public request for comments on the design of this feature.

The existing --tls-auth and tls-crypt options use a pre-shared group
key, which is shared amongst all clients and servers in an OpenVPN
deployment.  If any client or server is compromised, the attacker will
have access to this shared key, and it will no longer provide any
security.  To reduce the risk of loosing pre-shared keys, tls-crypt-v2
adds the ability to supply each client with a unique tls-crypt key.

Also, even if all peers succeed in keeping the key secret, the
--tls-crypt key lifetime is limited to roughly 8000 years, divided by
the number of clients (see the --tls-crypt section of the man page).
Using client-specific keys, we lift this lifetime requirement to roughly
8000 years for each client key (which "Should Be Enough For Everybody
(tm)").

The full specification is attached.  Antonio and I have been working on
an implementation, a preview is available on:
https://github.com/syzzer/openvpn/tree/tls-crypt-v2-preview
(NOT READY FOR PRODUCTION USE!  Also, this is not a stable branch and
might be force-pushed or disappear at any moment.)

Any comments (both on the design as well as the text), bug reports or
suggestions are welcome!

-Steffan

Client-specific tls-crypt keys (--tls-crypt-v2)
===============================================

This document describes the ``--tls-crypt-v2`` option, which enables OpenVPN
to use client-specific ``--tls-crypt`` keys.

Rationale
---------

``--tls-auth`` and ``tls-crypt`` use a pre-shared group key, which is shared
amongst all client and servers in an OpenVPN deployment.  If any client or
server is compromised, the attacker will have access to this shared key, and it
will no longer provide any security.  To reduce the risk of loosing pre-shared
keys, ``tls-crypt-v2`` adds the ability to supply each client with a unique
tls-crypt key.

``tls-crypt`` shares a group key amongst a lot of servers and clients.  Even if
all these peers succeed in keeping the key secret, the key lifetime is limited
to roughly 8000 years, divided by the number of clients (see the
``--tls-crypt`` section of the man page).  Using client-specific keys, we lift
this lifetime requirement to roughly 8000 years for each client key (which
"Should Be Enough For Everybody (tm)").


Implementation
--------------

Client-specific tls-crypt keys using an encrypted cookie mechanism.  The
mechanism works as follows:

When setting up a tls-crypt-v2 group (similar to generating a tls-crypt or
tls-auth key previously):

1. Generate a tls-crypt-v2 server key using OpenVPN's ``--genkey``.  This key
   contains 4 512-bit keys, of which we use:

   * the first 256 bits of key 1 as AES-256-CTR encryption key ``Ke``
   * the first 256 bits of key 2 as HMAC-SHA-256 authentication key ``Ka``

2. Add the tls-crypt-v2 server key to all server configs
   (``tls-crypt-v2 /path/to/server.key``)


When provisioning a client, create a client-specific tls-crypt key:

1. Generate 2048 bits client-specific key ``Kc``
2. Optionally generate metadata
3. Create a wrapped client key ``WKc``, using the same nonce-misuse-resistant
   SIV contruction we use for tls-crypt:

   ``T = HMAC-SHA256(Ka, Kc || metadata)``

   ``IV = 128 most significant bits of T``

   ``WKc = T || AES-256-CTR(Ke, IV, Kc || metadata)``

4. Create a tls-crypt-v2 client key: PEM-encode ``Kc || WKc`` and store in a
   file, using the header ``-----BEGIN OpenVPN tls-crypt-v2 client key-----``
   and the footer ``-----END OpenVPN tls-crypt-v2 client key-----``.  (The PEM
   format is simple, and following PEM allows us to use the crypto lib function
   for en/decoding.)
5. Add the tls-crypt-v2 client key to the client config
   (``tls-crypt-v2 /path/to/client-specific.key``)


When setting up the openvpn connection:

1. The client reads the tls-crypt-v2 key from its config, and:

   1. loads ``Kc`` as its tls-crypt key,
   2. stores ``WKc`` in memory for sending to the server.

2. To start the connection, the client creates a P_CONTROL_HARD_RESET_CLIENT_V3
   message with ``WKc`` as payload.  The entire message is authenticated as
   Additional Data using ``Kc`` (following the tls-crypt wrapping).

3. Server receives the P_CONTROL_HARD_RESET_CLIENT_V3 message, and

   a. unwraps ``WKc``.
   b. uses unwrapped ``Kc`` to verify the P_CONTROL_HARD_RESET_CLIENT_V3
      message's authentication.

   Packet is dropped and no error response is sent when either a or b fails (DoS
   protection).

4. Server optionally checks metadata using script/plugin
   (allows early abort of connnection, *before* dangerous TLS parsing).

   The metadata is checked *after* the OpenVPN three-way handshake has
   completed, to prevent DoS attacks.  (That is, once the client has proved to
   the server that it posesses Kc, by authenticating a packet that contains the
   session ID picked by the server.)

   RFC: should the server send a 'key rejected' message if the key is e.g.
   revoked or expired?  Allows for better client-side error reporting.

6. Client and server use ``Kc`` for (un)wrapping any following control channel
   messages.


Considerations
--------------

``tls-crypt-v2`` uses fixed crypto algorithms, because:

 * The crypto is used before we can do any negotiation, so the algorithms have
   to be predefined.
 * The crypto primitives are chosen conservatively, making problems with these
   primites unlikely.
 * Making anything configurable adds complexity, both in implementation and
   usage.  We should not add anymore complexity than is really neccessary.

``tls-crypt-v2`` pro's:

 * Allows user-specific keys
 * Allows revoking keys based on metadata
 * Flexible metadata allows simpler and more complex revocation schemes, e.g.:

   * No revocation
   * Use own key identifiers (e.g. when using username/password auth)
   * Use certificate fingerprint
   * Use certificate serial (+ CA fingerprint?), allows using CRL for revocation
   * Use own expiration mechanism

 * SIV using HMAC-SHA256 and AES-256-CTR is quantum resistent

``tls-crypt-v2`` con's:

 * Slightly more work un first connection (``WKc`` unwrap)
 * Flexible metadata allow mistakes
   (So we should make it easy to do it right.  Provide tooling in compat/ to
   create client keys based on cert serial + CA fingerprint, provide script that
   uses CRL (if available) to drop revoked cookies.)
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to