OpenVPN
Macros | Functions
Control channel encryption (–tls-crypt, –tls-crypt-v2)
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
 

Functions

void tls_crypt_init_key (struct key_ctx_bi *key, struct key2 *keydata, const char *key_file, bool key_inline, bool tls_server)
 Initialize a key_ctx_bi structure for use with –tls-crypt. More...
 
bool tls_session_generate_dynamic_tls_crypt_key (struct tls_multi *multi, struct tls_session *session)
 Generates a TLS-Crypt key to be used with dynamic tls-crypt using the TLS EKM exporter function. More...
 
int tls_crypt_buf_overhead (void)
 Returns the maximum overhead (in bytes) added to the destination buffer by tls_crypt_wrap(). 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, bool 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 key2 *original_key, struct buffer *wrapped_key_buf, const char *key_file, bool 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, bool 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.

◆ 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.

◆ TLS_CRYPT_OFF_PID

#define TLS_CRYPT_OFF_PID   (1 + SID_SIZE)

Definition at line 93 of file tls_crypt.h.

◆ 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.

◆ 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)

Definition at line 89 of file tls_crypt.h.

◆ TLS_CRYPT_V2_CLIENT_KEY_LEN

#define TLS_CRYPT_V2_CLIENT_KEY_LEN   (2048 / 8)

Definition at line 98 of file tls_crypt.h.

◆ TLS_CRYPT_V2_MAX_METADATA_LEN

#define TLS_CRYPT_V2_MAX_METADATA_LEN
Value:

Definition at line 101 of file tls_crypt.h.

◆ TLS_CRYPT_V2_MAX_WKC_LEN

#define TLS_CRYPT_V2_MAX_WKC_LEN   (1024)

Definition at line 97 of file tls_crypt.h.

◆ 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.

Function Documentation

◆ tls_crypt_buf_overhead()

int tls_crypt_buf_overhead ( void  )

◆ tls_crypt_init_key()

void tls_crypt_init_key ( struct key_ctx_bi key,
struct key2 keydata,
const char *  key_file,
bool  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 key itself if key_inline is true.
keydataThe keydata used to create key will be written here.
key_inlineTrue if key_file contains an inline key, False otherwise.
tls_serverMust be set to true is this is a TLS server instance.

Definition at line 61 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(), and init_tas_crypt().

◆ 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 613 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, tls_wrap_ctx::original_wrap_keydata, 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 key2 original_key,
struct buffer wrapped_key_buf,
const char *  key_file,
bool  key_inline 
)

Initialize a tls-crypt-v2 client key.

Parameters
keyKey structure to be initialized with the client key.
original_keycontains the key data that has been used to initialise the key parameter
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 the key itself if key_inline is true.
key_inlineTrue if key_file contains an inline key, False otherwise.

Definition at line 336 of file tls_crypt.c.

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

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,
bool  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. @parem encrypt If true, initialize the key structure for encryption, otherwise for decryption.
key_fileFile path of the key file to load or the key itself if key_inline is true.
key_inlineTrue if key_file contains an inline key, False otherwise.

Definition at line 362 of file tls_crypt.c.

References buf_set_write(), key_type::cipher, key_type::digest, init_key_ctx(), M_FATAL, msg, read_pem_key_file(), secure_memzero(), tls_crypt_kt(), 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,
bool  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.
key_fileFile path of the server key to use for wrapping the client key or the key itself if key_inline is true.
key_inlineTrue if key_file contains an inline key, False otherwise.

Definition at line 681 of file tls_crypt.c.

References alloc_buf_gc(), ASSERT, BCAP, BEND, BLEN, BPTR, buf_clear(), buf_inc_len(), buf_write(), buffer_write_file(), cleanup(), 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(), OPENVPN_BASE64_DECODED_LENGTH, rand_bytes(), secure_memzero(), streq, test_client_key, 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_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(), test_tls_crypt_v2_write_client_key_file(), and test_tls_crypt_v2_write_client_key_file_metadata().

◆ 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 675 of file tls_crypt.c.

References tls_crypt_v2_srv_pem_name, and write_pem_key_file().

Referenced by do_genkey(), and test_tls_crypt_v2_write_server_key_file().

◆ 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 145 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 test_tls_crypt_secure_reneg_key(), 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 tls_wrap_control().

◆ tls_session_generate_dynamic_tls_crypt_key()

bool tls_session_generate_dynamic_tls_crypt_key ( struct tls_multi multi,
struct tls_session session 
)

Generates a TLS-Crypt key to be used with dynamic tls-crypt using the TLS EKM exporter function.

All renegotiations of a session use the same generated dynamic key.

Parameters
multimulti session struct
sessionsession that will be used for the TLS EKM exporter
Returns
true iff generating the key was successful

Definition at line 98 of file tls_crypt.c.

References alloc_buf(), BUF_SIZE, EXPORT_DYNAMIC_TLS_CRYPT_LABEL, init_key_ctx_bi(), KEY_DIRECTION_INVERSE, KEY_DIRECTION_NORMAL, key_direction_state_init(), key_state_export_keying_material(), key2::keys, key2::n, packet_id_init(), secure_memzero(), tls_crypt_kt(), and xor_key2().

Referenced by test_tls_crypt_secure_reneg_key(), and tls_session_update_crypto_params_do_work().

TLS_CRYPT_V2_MAX_WKC_LEN
#define TLS_CRYPT_V2_MAX_WKC_LEN
Definition: tls_crypt.h:97
TLS_CRYPT_V2_TAG_SIZE
#define TLS_CRYPT_V2_TAG_SIZE
Definition: tls_crypt.h:100
TLS_CRYPT_V2_CLIENT_KEY_LEN
#define TLS_CRYPT_V2_CLIENT_KEY_LEN
Definition: tls_crypt.h:98