OpenVPN
Macros | Functions
Control channel encryption (--tls-crypt)
Collaboration diagram for Control channel encryption (--tls-crypt):

Macros

#define TLS_CRYPT_TAG_SIZE   (256/8)
 
#define TLS_CRYPT_PID_SIZE   (sizeof(packet_id_type) + sizeof(net_time_t))
 
#define TLS_CRYPT_BLOCK_SIZE   (128/8)
 
#define TLS_CRYPT_OFF_PID   (1 + SID_SIZE)
 
#define TLS_CRYPT_OFF_TAG   (TLS_CRYPT_OFF_PID + TLS_CRYPT_PID_SIZE)
 
#define TLS_CRYPT_OFF_CT   (TLS_CRYPT_OFF_TAG + TLS_CRYPT_TAG_SIZE)
 

Functions

void tls_crypt_init_key (struct key_ctx_bi *key, const char *key_file, const char *key_inline, bool tls_server)
 Initialize a key_ctx_bi structure for use with –tls-crypt. More...
 
int tls_crypt_buf_overhead (void)
 Returns the maximum overhead (in bytes) added to the destination buffer by tls_crypt_wrap(). More...
 
void tls_crypt_adjust_frame_parameters (struct frame *frame)
 Adjust frame parameters for –tls-crypt overhead. More...
 
bool tls_crypt_wrap (const struct buffer *src, struct buffer *dst, struct crypto_options *opt)
 Wrap a control channel packet (both authenticates and encrypts the data). More...
 
bool tls_crypt_unwrap (const struct buffer *src, struct buffer *dst, struct crypto_options *opt)
 Unwrap a control channel packet (decrypts, authenticates and performs replay checks). More...
 

Detailed Description

Control channel encryption uses a pre-shared static key (like the –tls-auth key) to encrypt control channel packets.
Encrypting control channel packets has three main advantages:
  • It provides more privacy by hiding the certificate used for the TLS connection.
  • It is harder to identify OpenVPN traffic as such.
  • It provides "poor-man's" post-quantum security, against attackers who will never know the pre-shared key (i.e. no forward secrecy).
Specification
Control channel encryption is based on the SIV construction [0], to achieve nonce misuse-resistant authenticated encryption:
msg = control channel plaintext
header = opcode (1 byte) || session_id (8 bytes) || packet_id (8 bytes)
Ka = authentication key (256 bits)
Ke = encryption key (256 bits)
(Ka and Ke are pre-shared keys, like with --tls-auth)
auth_tag = HMAC-SHA256(Ka, header || msg)
IV = 128 most-significant bits of auth_tag
ciph = AES256-CTR(Ke, IV, msg)
output = Header || Tag || Ciph
This boils down to the following on-the-wire packet format:
- opcode - || - session_id - || - packet_id - || auth_tag || * payload *
Where - XXX - means authenticated, and * XXX * means authenticated and encrypted.

Macro Definition Documentation

◆ TLS_CRYPT_BLOCK_SIZE

#define TLS_CRYPT_BLOCK_SIZE   (128/8)

Definition at line 85 of file tls_crypt.h.

Referenced by tls_crypt_buf_overhead(), tls_crypt_unwrap(), and tls_crypt_wrap().

◆ TLS_CRYPT_OFF_CT

#define TLS_CRYPT_OFF_CT   (TLS_CRYPT_OFF_TAG + TLS_CRYPT_TAG_SIZE)

Definition at line 89 of file tls_crypt.h.

Referenced by tls_crypt_unwrap().

◆ TLS_CRYPT_OFF_PID

#define TLS_CRYPT_OFF_PID   (1 + SID_SIZE)

Definition at line 87 of file tls_crypt.h.

Referenced by tls_crypt_unwrap().

◆ TLS_CRYPT_OFF_TAG

#define TLS_CRYPT_OFF_TAG   (TLS_CRYPT_OFF_PID + TLS_CRYPT_PID_SIZE)

Definition at line 88 of file tls_crypt.h.

Referenced by tls_crypt_unwrap().

◆ TLS_CRYPT_PID_SIZE

#define TLS_CRYPT_PID_SIZE   (sizeof(packet_id_type) + sizeof(net_time_t))

Definition at line 84 of file tls_crypt.h.

◆ TLS_CRYPT_TAG_SIZE

#define TLS_CRYPT_TAG_SIZE   (256/8)

Definition at line 83 of file tls_crypt.h.

Referenced by tls_crypt_buf_overhead(), tls_crypt_unwrap(), and tls_crypt_wrap().

Function Documentation

◆ tls_crypt_adjust_frame_parameters()

void tls_crypt_adjust_frame_parameters ( struct frame frame)

Adjust frame parameters for –tls-crypt overhead.

Definition at line 84 of file tls_crypt.c.

References D_MTU_DEBUG, frame_add_to_extra_frame(), msg, and tls_crypt_buf_overhead().

Referenced by do_init_crypto_tls().

◆ tls_crypt_buf_overhead()

int tls_crypt_buf_overhead ( void  )

Returns the maximum overhead (in bytes) added to the destination buffer by tls_crypt_wrap().

Definition at line 63 of file tls_crypt.c.

References packet_id_size(), TLS_CRYPT_BLOCK_SIZE, and TLS_CRYPT_TAG_SIZE.

Referenced by tls_crypt_adjust_frame_parameters(), tls_crypt_fail_msg_too_long(), and tls_crypt_loopback_max_len().

◆ tls_crypt_init_key()

void tls_crypt_init_key ( struct key_ctx_bi key,
const char *  key_file,
const char *  key_inline,
bool  tls_server 
)

Initialize a key_ctx_bi structure for use with –tls-crypt.

Parameters
keyThe key context to initialize
key_fileThe file to read the key from (or the inline tag to indicate and inline key).
key_inlineArray containing (zero-terminated) inline key, or NULL if not used.
tls_serverMust be set to true is this is a TLS server instance.

Definition at line 69 of file tls_crypt.c.

References key_type::cipher, crypto_read_openvpn_key(), key_type::digest, KEY_DIRECTION_INVERSE, KEY_DIRECTION_NORMAL, M_FATAL, msg, and tls_crypt_kt().

Referenced by do_init_crypto_tls_c1().

◆ tls_crypt_unwrap()

bool tls_crypt_unwrap ( const struct buffer src,
struct buffer dst,
struct crypto_options opt 
)

◆ tls_crypt_wrap()

bool tls_crypt_wrap ( const struct buffer src,
struct buffer dst,
struct crypto_options opt 
)

Wrap a control channel packet (both authenticates and encrypts the data).

Parameters
srcData to authenticate and encrypt.
dstAny data present in this buffer is first authenticated, then the wrapped packet id and data from the src buffer are appended. Must have at least tls_crypt_buf_overhead()+BLEN(src) headroom.
optThe crypto state for this –tls-crypt instance.
Returns
true iff wrapping succeeded.

Definition at line 94 of file tls_crypt.c.

References ASSERT, BEND, BLEN, BPTR, buf_inc_len(), buf_safe(), buf_write_alloc(), buffer::capacity, key_ctx::cipher, cipher_ctx_final(), cipher_ctx_reset(), cipher_ctx_update(), crypto_clear_error(), D_CRYPT_ERRORS, D_PACKET_CONTENT, dmsg, key_ctx_bi::encrypt, format_hex(), gc_free(), gc_init(), key_ctx::hmac, hmac_ctx_final(), hmac_ctx_reset(), hmac_ctx_size(), hmac_ctx_update(), crypto_options::key_ctx_bi, buffer::len, msg, buffer::offset, crypto_options::packet_id, packet_id_initialized(), packet_id_write(), packet_id::send, TLS_CRYPT_BLOCK_SIZE, and TLS_CRYPT_TAG_SIZE.

Referenced by tls_crypt_fail_invalid_key(), tls_crypt_fail_msg_too_long(), tls_crypt_fail_replay(), tls_crypt_ignore_replay(), tls_crypt_loopback(), tls_crypt_loopback_max_len(), tls_crypt_loopback_zero_len(), and write_control_auth().