OpenVPN
Macros | Functions
Control channel encryption (--tls-crypt, --tls-crypt-v2)

Control channel encryption uses a pre-shared static key (like the –tls-auth key) to encrypt control channel packets. More...

Collaboration diagram for Control channel encryption (--tls-crypt, --tls-crypt-v2):

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)
 
#define TLS_CRYPT_V2_MAX_WKC_LEN   (1024)
 
#define TLS_CRYPT_V2_CLIENT_KEY_LEN   (2048 / 8)
 
#define TLS_CRYPT_V2_SERVER_KEY_LEN   (sizeof(struct key))
 
#define TLS_CRYPT_V2_TAG_SIZE   (TLS_CRYPT_TAG_SIZE)
 
#define TLS_CRYPT_V2_MAX_METADATA_LEN
 
#define TLS_CRYPT_V2_MAX_B64_METADATA_LEN   OPENVPN_BASE64_LENGTH(TLS_CRYPT_V2_MAX_METADATA_LEN - 1)
 

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...
 
void tls_crypt_v2_init_server_key (struct key_ctx *key_ctx, bool encrypt, const char *key_file, const char *key_inline)
 Initialize a tls-crypt-v2 server key (used to encrypt/decrypt client keys). More...
 
void tls_crypt_v2_init_client_key (struct key_ctx_bi *key, struct buffer *wrapped_key_buf, const char *key_file, const char *key_inline)
 Initialize a tls-crypt-v2 client key. More...
 
bool tls_crypt_v2_extract_client_key (struct buffer *buf, struct tls_wrap_ctx *ctx, const struct tls_options *opt)
 Extract a tls-crypt-v2 client key from a P_CONTROL_HARD_RESET_CLIENT_V3 message, and load the key into the supplied tls wrap context. More...
 
void tls_crypt_v2_write_server_key_file (const char *filename)
 Generate a tls-crypt-v2 server key, and write to file. More...
 
void tls_crypt_v2_write_client_key_file (const char *filename, const char *b64_metadata, const char *key_file, const char *key_inline)
 Generate a tls-crypt-v2 client key, and write to file. 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:

–tls-crypt uses a tls-auth-style group key, where all servers and clients share the same group key. –tls-crypt-v2 adds support for client-specific keys, where all servers share the same client-key encryption key, and each clients receives a unique client key, both in plaintext and in encrypted form. When connecting to a server, the client sends the encrypted key to the server in the first packet (P_CONTROL_HARD_RESET_CLIENT_V3). The server then decrypts that key, and both parties can use the same client-specific key for tls-crypt packets. See doc/tls-crypt-v2.txt for more details.

On-the-wire tls-crypt packet 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 91 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 95 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 93 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 94 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 90 of file tls_crypt.h.

◆ TLS_CRYPT_TAG_SIZE

#define TLS_CRYPT_TAG_SIZE   (256/8)

◆ TLS_CRYPT_V2_CLIENT_KEY_LEN

#define TLS_CRYPT_V2_CLIENT_KEY_LEN   (2048 / 8)

Definition at line 98 of file tls_crypt.h.

Referenced by tls_crypt_v2_init_client_key(), and tls_crypt_v2_write_client_key_file().

◆ TLS_CRYPT_V2_MAX_B64_METADATA_LEN

#define TLS_CRYPT_V2_MAX_B64_METADATA_LEN   OPENVPN_BASE64_LENGTH(TLS_CRYPT_V2_MAX_METADATA_LEN - 1)

Definition at line 104 of file tls_crypt.h.

Referenced by tls_crypt_v2_write_client_key_file().

◆ TLS_CRYPT_V2_MAX_METADATA_LEN

#define TLS_CRYPT_V2_MAX_METADATA_LEN

◆ TLS_CRYPT_V2_MAX_WKC_LEN

#define TLS_CRYPT_V2_MAX_WKC_LEN   (1024)

◆ TLS_CRYPT_V2_SERVER_KEY_LEN

#define TLS_CRYPT_V2_SERVER_KEY_LEN   (sizeof(struct key))

Definition at line 99 of file tls_crypt.h.

◆ TLS_CRYPT_V2_TAG_SIZE

#define TLS_CRYPT_V2_TAG_SIZE   (TLS_CRYPT_TAG_SIZE)

Definition at line 100 of file tls_crypt.h.

Referenced by tls_crypt_v2_wrap_client_key().

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 96 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 75 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 81 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_tls_wrap_key().

◆ tls_crypt_unwrap()

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

◆ tls_crypt_v2_extract_client_key()

bool tls_crypt_v2_extract_client_key ( struct buffer buf,
struct tls_wrap_ctx ctx,
const struct tls_options opt 
)

Extract a tls-crypt-v2 client key from a P_CONTROL_HARD_RESET_CLIENT_V3 message, and load the key into the supplied tls wrap context.

Parameters
bufBuffer containing a received P_CONTROL_HARD_RESET_CLIENT_V3 message.
ctxtls-wrap context to be initialized with the client key.
Returns
true if a key was successfully extracted.

Definition at line 609 of file tls_crypt.c.

References alloc_buf(), ASSERT, BEND, BLEN, buf_advance(), buf_inc_len(), key_ctx::cipher, tls_wrap_ctx::cleanup_key_ctx, CO_PACKET_ID_LONG_FORM, D_HANDSHAKE, D_TLS_ERRORS, crypto_options::flags, crypto_options::key_ctx_bi, tls_wrap_ctx::mode, msg, tls_wrap_ctx::opt, secure_memzero(), tls_crypt_v2_load_client_key(), TLS_CRYPT_V2_MAX_METADATA_LEN, tls_wrap_ctx::tls_crypt_v2_metadata, tls_wrap_ctx::tls_crypt_v2_server_key, tls_crypt_v2_unwrap_client_key(), tls_crypt_v2_verify_metadata(), and tls_options::tls_crypt_v2_verify_script.

Referenced by read_control_auth(), and tls_crypt_v2_wrap_unwrap_max_metadata().

◆ tls_crypt_v2_init_client_key()

void tls_crypt_v2_init_client_key ( struct key_ctx_bi key,
struct buffer wrapped_key_buf,
const char *  key_file,
const char *  key_inline 
)

Initialize a tls-crypt-v2 client key.

Parameters
keyKey structure to be initialized with the client key.
wrapped_key_bufReturns buffer containing the wrapped key that will be sent to the server when connecting. Caller must free this buffer when no longer needed.
key_fileFile path of the key file to load, or INLINE tag.
key_inlineInline key file contents (or NULL if not inline).

Definition at line 336 of file tls_crypt.c.

References alloc_buf(), buf_read(), key2::keys, M_FATAL, msg, secure_memzero(), tls_crypt_v2_cli_pem_name, TLS_CRYPT_V2_CLIENT_KEY_LEN, tls_crypt_v2_load_client_key(), TLS_CRYPT_V2_MAX_WKC_LEN, and tls_crypt_v2_read_keyfile().

Referenced by do_init_tls_wrap_key(), and tls_crypt_v2_write_client_key_file().

◆ tls_crypt_v2_init_server_key()

void tls_crypt_v2_init_server_key ( struct key_ctx key_ctx,
bool  encrypt,
const char *  key_file,
const char *  key_inline 
)

Initialize a tls-crypt-v2 server key (used to encrypt/decrypt client keys).

Parameters
keyKey structure to be initialized. Must be non-NULL. encrypt If true, initialize the key structure for encryption, otherwise for decryption.
key_fileFile path of the key file to load, or INLINE tag.
key_inlineInline key file contents (or NULL if not inline).

Definition at line 361 of file tls_crypt.c.

References buf_set_write(), key_type::cipher, key_type::digest, init_key_ctx(), M_FATAL, msg, secure_memzero(), tls_crypt_kt(), tls_crypt_v2_read_keyfile(), and tls_crypt_v2_srv_pem_name.

Referenced by do_init_tls_wrap_key(), and tls_crypt_v2_write_client_key_file().

◆ tls_crypt_v2_write_client_key_file()

void tls_crypt_v2_write_client_key_file ( const char *  filename,
const char *  b64_metadata,
const char *  key_file,
const char *  key_inline 
)

Generate a tls-crypt-v2 client key, and write to file.

Parameters
filenameFilename of the client key file to create.
b64_metadataBase64 metadata to be included in the client key.
server_key_fileFile path of the server key to use for wrapping the client key, or INLINE tag.
server_key_inlineInline server key file contents (or NULL if not inline).

Definition at line 705 of file tls_crypt.c.

References alloc_buf_gc(), ASSERT, BCAP, BPTR, buf_clear(), buf_inc_len(), buf_write(), buffer_write_file(), crypto_pem_encode(), D_GENKEY, free_buf(), free_key_ctx(), free_key_ctx_bi(), gc_free(), gc_new(), htonll, key2::keys, M_FATAL, msg, now, openvpn_base64_decode(), rand_bytes(), secure_memzero(), TLS_CRYPT_METADATA_TYPE_TIMESTAMP, TLS_CRYPT_METADATA_TYPE_USER, tls_crypt_v2_cli_pem_name, TLS_CRYPT_V2_CLIENT_KEY_LEN, tls_crypt_v2_init_client_key(), tls_crypt_v2_init_server_key(), TLS_CRYPT_V2_MAX_B64_METADATA_LEN, TLS_CRYPT_V2_MAX_METADATA_LEN, TLS_CRYPT_V2_MAX_WKC_LEN, tls_crypt_v2_unwrap_client_key(), and tls_crypt_v2_wrap_client_key().

Referenced by do_genkey().

◆ tls_crypt_v2_write_server_key_file()

void tls_crypt_v2_write_server_key_file ( const char *  filename)

Generate a tls-crypt-v2 server key, and write to file.

Parameters
filenameFilename of the server key file to create.

Definition at line 671 of file tls_crypt.c.

References buf_clear(), buf_set_read(), buffer_write_file(), clear_buf(), crypto_pem_encode(), gc_free(), gc_new(), M_ERR, M_NONFATAL, M_WARN, msg, rand_bytes(), secure_memzero(), and tls_crypt_v2_srv_pem_name.

Referenced by do_genkey().

◆ 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 106 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().