> This boils down to the following on-the-wire packet format:
> 
>    -opcode- || -session_id- || -packet_id- || auth_tag || * payload *

I am pretty that opcode is *not* authenticated looking the code. Which
is probably not a problem but should not be documented as authenticated.
(There is a buf_advance(buf ,1) before calling the unwrap function.

>    Where
>    - XXX - means authenticated, and
>    * XXX * means authenticated and encrypted.

This misalignes the rest of the packet. I am not sure how big the
penality actually is but we have DATA_V2 and COMP_V2 fix this
misalignment. But then again ignore my comment for control channel traffic.

For the packet format I think it would be very good to add a key id to
help transisition or allow more paranoid people to have a a key per
client. In the server you would specify all allowed valid keys together
with their ids (or somehow emded that id/read that id from keyfile). Not
that saying that this should be implement in the first version of the
patch but something that we can implement later without having a
tls-crypt and a tls-crypt v2 packet format.
> 
> Which is very similar to the current tls-auth packet format, and has the
> same overhead as "--tls-auth" with "--auth SHA256".
> 
> The use of a nonce misuse-resistant authenticated encryption scheme
> allows us to worry less about the risks of nonce collisions.  This is
> important, because in contrast with the data channel in TLS mode, we
> will not be able to rotate tls-crypt keys often or fully guarantee nonce
> uniqueness.  For non misuse-resistant modes such as GCM [1], [2], the
> data channel in TLS mode only has to ensure that the packet counter
> never rolls over, while tls-crypt would have to provide nonce uniqueness
> over all control channel packets sent by all clients, for the lifetime
> of the tls-crypt key.
> 
> Unlike with tls-auth, no --key-direction has to be specified for
> tls-crypt.  TLS servers always use key direction 1, and TLS clients
> always use key direction 2, which means that client->server traffic and
> server->client traffic always use different keys, without requiring
> configuration.
> 
> Using fixed, secure, encryption and authentication algorithms makes both
> implementation and configuration easier.  If we ever want to, we can
> extend this to support other crypto primitives.  Since tls-crypt should
> provide privacy as well as DoS protection, these should not be made
> negotiable.
> 
> Security considerations:
> ------------------------
> 
> tls-crypt is a best-effort mechanism that aims to provide as much
> privacy and security as possible, while staying as simple as possible.
> The following are some security considerations for this scheme.
> 
> 1. The same tls-crypt key is potentially shared by a lot of peers, so it
>    is quite likely to get compromised.  Once an attacker acquires the
>    tls-crypt key, this mechanism no longer provides any security against
>    the attacker.
> 
> 2. Since many peers potentially use the tls-crypt key for a long time, a
>    lot of data might be encrypted under the tls-crypt key.  This leads
>    to two potential problems:
> 
>    * The "opcode || session id || packet id" combination might collide.
>      This might happen in larger setups, because the session id contains
>      just 64 bits or random.  Using the uniqueness requirement from the
Typo: of random

>      GCM spec [3] (a collision probability of less than 2^(-32)),
>      uniqueness is achieved when using the tls-crypt key for at most
>      2^16 (65536) connections per process start.  (The packet id
>      includes the daemon start time in the packet ID, which should be
>      different after stopping and (re)starting OpenPVN.)
> 
>      And if a collision happens, an attacker can *only* learn whether
>      colliding packets contain the same plaintext.  Attackers will not
>      be able to learn anything else about the plaintext (unless the
>      attacker knows the plaintext of one of these packets, of course).
>      Since the impact is limited, I consider this an acceptable
>      remaining risk.
> 
>    * The IVs used in encryption might collide.  When two IVs collide, an
>      attacker can learn the xor of the two plaintexts by xorring the
>      ciphertexts.  This is a serious loss of confidentiality.  The IVs
>      are 128-bit, so when HMAC-SHA256 is a secure PRF (an assumption
>      that must also hold for TLS), and we use the same uniqueness
>      requirement from [3], this limits the total amount of control
>      channel messages for all peers in the setup to 2^48.  Assuming a
>      large setup of 2^16 (65536) clients, and a (conservative) number of
>      2^16 control channel packets per connection on average, this means
>      that clients may set up 2^16 connections on average.  I think these
>      numbers are reasonable.
> 
> (I have a follow-up proposal to use client-specific tls-auth/tls-crypt
> keys to partially mitigate these issues, but let's tackle this patch
> first.)

How does the server know which packet Id to use? Part of opcode, e.g.
some bits there or part of the session id.


> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#elif defined(_MSC_VER)
> +#include "config-msvc.h"
> +#endif
> +
> +#include "syshead.h"
> +
> +#ifdef ENABLE_CRYPTO
> +#include "crypto.h"
> +#include "session_id.h"
> +
> +#include "tls_crypt.h"
> +
> +int tls_crypt_buf_overhead(void)
> +{
> +  return packet_id_size (true) + TLS_CRYPT_TAG_SIZE + TLS_CRYPT_BLOCK_SIZE;
> +}
> +
> +void
> +tls_crypt_init_key (struct key_ctx_bi *key, const char *key_file,
> +    const char *key_inline, bool tls_server) {
> +  struct key_type kt;
> +
> +  kt.cipher = cipher_kt_get ("AES-256-CTR");

This can fail, if we are on a weird OpenSSL library. We assert later
(ctx->cipher). I think you should also add an ASSERT/M_FATAL here that
gives gives a clear indication that the crypto library does not support
AES-256-CTR.

> +  kt.cipher_length = cipher_kt_key_size (kt.cipher);
> +  kt.digest = md_kt_get ("SHA256");
Same here.



> +  gc_init (&gc);
> +
> +  dmsg (D_PACKET_CONTENT, "TLS-CRYPT WRAP FROM: %s",
> +      format_hex (BPTR (src), BLEN (src), 80, &gc));
> +
> +  /* Get packet ID */
> +  {
> +    struct packet_id_net pin;
> +    packet_id_alloc_outgoing (&opt->packet_id.send, &pin, true);
> +    packet_id_write (&pin, dst, true, false);
> +  }
> +
> +  dmsg (D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s",
> +      format_hex (BPTR (dst), BLEN (dst), 0, &gc));
> +
> +  /* Buffer overflow check */
> +  if (!buf_safe (dst, BLEN (src) + TLS_CRYPT_BLOCK_SIZE + 
> TLS_CRYPT_TAG_SIZE))

This does not take the opcode into account

> +    {
> +      msg (D_CRYPT_ERRORS, "TLS-CRYPT WRAP: buffer size error, "
> +       "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->capacity, src->offset,
> +       src->len, dst->capacity, dst->offset, dst->len);
> +      goto err;
> +    }
> +
> +  /* Calculate auth tag and synthetic IV */
> +  {
> +    uint8_t *tag = NULL;
> +    hmac_ctx_reset (ctx->hmac);
> +    hmac_ctx_update (ctx->hmac, BPTR (dst), BLEN (dst));
> +    hmac_ctx_update (ctx->hmac, BPTR (src), BLEN (src));
> +
> +    ASSERT (tag = buf_write_alloc (dst, TLS_CRYPT_TAG_SIZE));
> +    hmac_ctx_final (ctx->hmac, tag);
> +
> +    dmsg (D_PACKET_CONTENT, "TLS-CRYPT WRAP TAG: %s",
> +        format_hex (tag, TLS_CRYPT_TAG_SIZE, 0, &gc));
> +
> +    cipher_ctx_reset (ctx->cipher, tag);
> +  }
> +
> +  /* Encrypt src */
> +  {
> +    int outlen = 0;
> +    ASSERT (cipher_ctx_update (ctx->cipher, BEND (dst), &outlen,
> +     BPTR (src), BLEN(src)));

Indentation is wrong here.

> +    ASSERT (buf_inc_len (dst, outlen));
> +    ASSERT (cipher_ctx_final (ctx->cipher, BPTR (dst), &outlen));
> +    ASSERT (buf_inc_len (dst, outlen));
> +  }
> +
> +  dmsg (D_PACKET_CONTENT, "TLS-CRYPT WRAP TO: %s",
> +      format_hex (BPTR (dst), BLEN (dst), 80, &gc));
> +
> +  gc_free (&gc);
> +  return true;
> +


Otherwise all looks. Note that I have not extensively tested it so far
but more looked on the sourcecode and crypto stuff.

Arne

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to