Go to the documentation of this file.
51 return create_kt(
"AES-256-CTR",
"SHA256",
"tls-crypt");
62 const char *key_file,
bool key_inline,
bool tls_server)
64 const int key_direction = tls_server ?
69 msg(
M_FATAL,
"ERROR: --tls-crypt not supported");
72 "Control Channel Encryption",
"tls-crypt", keydata);
82 for (
int k = 0; k < 2; k++)
102 session->tls_wrap_reneg.mode = TLS_WRAP_CRYPT;
103 session->tls_wrap_reneg.cleanup_key_ctx =
true;
105 session->tls_wrap_reneg.opt.pid_persist = NULL;
110 "TLS_WRAP_RENEG",
session->key_id);
113 struct key2 rengokeys;
116 rengokeys.
keys,
sizeof(rengokeys.
keys)))
122 if (
session->tls_wrap.mode == TLS_WRAP_CRYPT
123 ||
session->tls_wrap.mode == TLS_WRAP_AUTH)
128 const int key_direction =
session->opt->server ?
137 &kt,
"dynamic tls-crypt");
176 "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->
capacity, src->
offset,
225 static const char error_prefix[] =
"tls-crypt unwrap error";
292 format_hex(tag_check,
sizeof(tag_check), 0, &gc));
324 const int key_direction = tls_server ?
329 msg(
M_FATAL,
"ERROR: --tls-crypt-v2 not supported");
332 "Control Channel Encryption");
337 struct buffer *wkc_buf,
const char *key_file,
344 key_file, key_inline))
346 msg(
M_FATAL,
"ERROR: invalid tls-crypt-v2 client key format");
352 msg(
M_FATAL,
"ERROR: not enough data in tls-crypt-v2 client key");
356 *original_key =
key2;
358 *wkc_buf = client_key;
363 const char *key_file,
bool key_inline)
366 struct buffer srv_key_buf;
368 buf_set_write(&srv_key_buf, (
void *)&srv_key,
sizeof(srv_key));
370 key_file, key_inline))
372 msg(
M_FATAL,
"ERROR: invalid tls-crypt-v2 server key format");
378 msg(
M_FATAL,
"ERROR: --tls-crypt-v2 not supported");
386 const struct key2 *src_key,
387 const struct buffer *src_metadata,
398 msg(
M_WARN,
"ERROR: could not write tag");
401 uint16_t net_len = htons(
sizeof(src_key->
keys) +
BLEN(src_metadata)
422 msg(
M_WARN,
"ERROR: could not crypt: insufficient space in dst");
429 (
void *)src_key->
keys,
sizeof(src_key->
keys)));
432 BPTR(src_metadata),
BLEN(src_metadata)));
443 struct buffer wrapped_client_key,
446 const char *error_prefix = __func__;
453 struct buffer plaintext = { 0 };
457 BLEN(&wrapped_client_key),
466 uint16_t net_len = 0;
467 const uint8_t *tag =
BPTR(&wrapped_client_key);
469 if (
BLEN(&wrapped_client_key) <
sizeof(net_len))
473 memcpy(&net_len,
BEND(&wrapped_client_key) -
sizeof(net_len),
476 if (ntohs(net_len) !=
BLEN(&wrapped_client_key))
479 ntohs(net_len),
BLEN(&wrapped_client_key));
483 buf_inc_len(&wrapped_client_key, -(
int)
sizeof(net_len));
494 buf_set_write(&plaintext, plaintext_buf_data,
sizeof(plaintext_buf_data));
497 BPTR(&wrapped_client_key),
498 BLEN(&wrapped_client_key)))
523 format_hex(tag_check,
sizeof(tag_check), 0, &gc));
526 "a different tls-crypt-v2 server key)");
529 if (
buf_len(&plaintext) <
sizeof(client_key->
keys))
533 memcpy(&client_key->
keys,
BPTR(&plaintext),
sizeof(client_key->
keys));
537 if (!
buf_copy(metadata, &plaintext))
539 CRYPT_ERROR(
"metadata too large for supplied buffer");
559 const char *tmp_file = NULL;
562 if (metadata_type < 0)
572 msg(
M_WARN,
"ERROR: could not write metadata to file");
576 char metadata_type_str[4] = { 0 };
577 snprintf(metadata_type_str,
sizeof(metadata_type_str),
578 "%i", (uint8_t) metadata_type);
595 msg(
M_WARN,
"WARNING: failed to remove temp file '%s", tmp_file);
620 "Client wants tls-crypt-v2, but no server key present.");
626 struct buffer wrapped_client_key = *buf;
627 uint16_t net_len = 0;
629 if (
BLEN(&wrapped_client_key) <
sizeof(net_len))
634 memcpy(&net_len,
BEND(&wrapped_client_key) -
sizeof(net_len),
637 size_t wkc_len = ntohs(net_len);
638 if (!
buf_advance(&wrapped_client_key,
BLEN(&wrapped_client_key) - wkc_len))
656 ctx->
mode = TLS_WRAP_CRYPT;
682 const char *b64_metadata,
683 const char *server_key_file,
684 bool server_key_inline)
687 struct key_ctx server_key = { 0 };
688 struct buffer client_key_pem = { 0 };
691 struct key2 client_key = { 2 };
695 msg(
M_FATAL,
"ERROR: could not generate random key");
703 size_t b64_length = strlen(b64_metadata);
710 msg(
M_FATAL,
"ERROR: failed to base64 decode provided metadata");
716 "ERROR: metadata too long (%d bytes, max %u bytes)",
725 int64_t timestamp =
htonll((uint64_t)
now);
735 msg(
M_FATAL,
"ERROR: could not wrap generated client key");
743 msg(
M_FATAL,
"ERROR: could not PEM-encode client key");
747 const char *client_file = filename;
748 bool client_inline =
false;
750 if (!filename ||
streq(filename,
""))
752 printf(
"%.*s\n",
BLEN(&client_key_pem),
BPTR(&client_key_pem));
753 client_file = (
const char *)
BPTR(&client_key_pem);
754 client_inline =
true;
758 msg(
M_FATAL,
"ERROR: could not write client key file");
764 struct buffer test_wrapped_client_key;
766 msg(
D_GENKEY,
"Testing client-side key loading...");
768 client_file, client_inline);
774 struct key2 test_client_key2 = { 0 };
778 msg(
D_GENKEY,
"Testing server-side key loading...");
780 test_wrapped_client_key, &server_key));
static bool buf_safe(const struct buffer *buf, size_t len)
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
int openvpn_base64_decode(const char *str, void *data, int size)
int n
The number of key objects stored in the key2.keys array.
static bool tls_crypt_v2_verify_metadata(const struct tls_wrap_ctx *ctx, const struct tls_options *opt)
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).
static bool buf_read(struct buffer *src, void *dest, int size)
#define TLS_CRYPT_V2_MAX_METADATA_LEN
struct key2 original_wrap_keydata
original key data to be xored in to the key for dynamic tls-crypt.
static struct gc_arena gc_new(void)
mbedtls_md_context_t hmac_ctx_t
Generic HMAC context.
#define EXPORT_DYNAMIC_TLS_CRYPT_LABEL
int len
Length in bytes of the actual content within the allocated memory.
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
void env_set_destroy(struct env_set *es)
#define TLS_CRYPT_V2_MAX_WKC_LEN
#define KEY_DIRECTION_NORMAL
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).
void tls_crypt_v2_init_client_key(struct key_ctx_bi *key, struct key2 *original_key, struct buffer *wkc_buf, const char *key_file, bool key_inline)
Initialize a tls-crypt-v2 client key.
int capacity
Size in bytes of memory allocated by malloc().
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
static int openvpn_run_script(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *hook)
Will run a script and return the exit code of the script if between 0 and 255, -1 otherwise.
void tls_crypt_v2_write_client_key_file(const char *filename, const char *b64_metadata, const char *server_key_file, bool server_key_inline)
Generate a tls-crypt-v2 client key, and write to file.
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
cipher_ctx_t * cipher
Generic cipher context.
void buf_clear(struct buffer *buf)
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
#define KEY_DIRECTION_INVERSE
static bool packet_id_initialized(const struct packet_id *pid)
Is this struct packet_id initialized?
static bool buf_copy(struct buffer *dest, const struct buffer *src)
void hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
void argv_msg_prefix(const int msglev, const struct argv *a, const char *prefix)
Similar to argv_msg() but prefixes the messages being written with a given string.
void argv_parse_cmd(struct argv *argres, const char *cmdstr)
Parses a command string, tokenizes it and puts each element into a separate struct argv argument slot...
void key_direction_state_init(struct key_direction_state *kds, int key_direction)
static const uint8_t TLS_CRYPT_METADATA_TYPE_USER
Metadata contains user-specified data.
#define TLS_CRYPT_BLOCK_SIZE
uint8_t hmac[MAX_HMAC_KEY_LENGTH]
Key material for HMAC operations.
int tls_crypt_buf_overhead(void)
Returns the maximum overhead (in bytes) added to the destination buffer by tls_crypt_wrap().
#define TLS_CRYPT_OFF_TAG
#define MAX_CIPHER_KEY_LENGTH
Security parameter state for a single VPN tunnel.
#define TLS_CRYPT_OFF_PID
int cipher_ctx_final(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len)
Pads the final cipher block using PKCS padding, and output to the destination buffer.
void crypto_read_openvpn_key(const struct key_type *key_type, struct key_ctx_bi *ctx, const char *key_file, bool key_inline, const int key_direction, const char *key_name, const char *opt_name, struct key2 *keydata)
void init_key_ctx_bi(struct key_ctx_bi *ctx, const struct key2 *key2, int key_direction, const struct key_type *kt, const char *name)
Container for unidirectional cipher and HMAC key material.
void free_key_ctx_bi(struct key_ctx_bi *ctx)
Container for two sets of OpenSSL cipher and/or HMAC contexts for both sending and receiving directio...
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
struct crypto_options opt
Crypto state.
#define MAX_HMAC_KEY_LENGTH
struct key_ctx tls_crypt_v2_server_key
Decrypts client keys.
static bool buf_advance(struct buffer *buf, int size)
static bool buf_inc_len(struct buffer *buf, int inc)
static struct key_type tls_crypt_kt(void)
static void tls_crypt_v2_load_client_key(struct key_ctx_bi *key, const struct key2 *key2, bool tls_server)
static bool tls_crypt_v2_wrap_client_key(struct buffer *wkc, const struct key2 *src_key, const struct buffer *src_metadata, struct key_ctx *server_key, struct gc_arena *gc)
Key ordering of the key2.keys array.
const char * digest
Message digest static parameters.
Control channel wrapping (–tls-auth/–tls-crypt) context.
mbedtls_cipher_context_t cipher_ctx_t
Generic cipher context.
void init_key_ctx(struct key_ctx *ctx, const struct key *key, const struct key_type *kt, int enc, const char *prefix)
int cipher_ctx_update(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len)
Updates the given cipher context, encrypting data in the source buffer, and placing any complete bloc...
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).
Container for one set of cipher and/or HMAC contexts.
#define OPENVPN_BASE64_DECODED_LENGTH(base64_length)
Compute the maximal number of bytes encoded in a base64 string.
struct buffer tls_crypt_v2_metadata
Received from client.
void crypto_clear_error(void)
const char * tls_crypt_v2_verify_script
const char * tls_crypt_v2_cli_pem_name
static const char * test_client_key
static const uint8_t TLS_CRYPT_METADATA_TYPE_TIMESTAMP
Metadata contains a 64-bit unix timestamp in network byte order.
void hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
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.
bool key_state_export_keying_material(struct tls_session *session, const char *label, size_t label_size, void *ekm, size_t ekm_size)
Keying Material Exporters [RFC 5705] allows additional keying material to be derived from existing TL...
Wrapper structure for dynamically allocated memory.
void hmac_ctx_reset(hmac_ctx_t *ctx)
int rand_bytes(uint8_t *output, int len)
Wrapper for secure random number generator.
#define TLS_CRYPT_V2_TAG_SIZE
static bool buf_write(struct buffer *dest, const void *src, size_t size)
int cipher_ctx_block_size(const cipher_ctx_t *ctx)
Returns the block size of the cipher, in bytes.
Security parameter state of a single session within a VPN tunnel.
struct env_set * env_set_create(struct gc_arena *gc)
static struct key_type create_kt(const char *cipher, const char *md, const char *optname)
Creates and validates an instance of struct key_type with the provided algs.
Garbage collection arena used to keep track of dynamically allocated memory.
void setenv_str(struct env_set *es, const char *name, const char *value)
bool crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src, struct gc_arena *gc)
Encode binary data as PEM.
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
const char * cipher
const name of the cipher
static bool tls_crypt_v2_unwrap_client_key(struct key2 *client_key, struct buffer *metadata, struct buffer wrapped_client_key, struct key_ctx *server_key)
int offset
Offset in bytes of the actual content within the allocated memory.
bool packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form, bool prepend)
Write a packet ID to buf, and update the packet ID state.
#define CRYPT_ERROR(format)
const char * tls_crypt_v2_srv_pem_name
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
void free_buf(struct buffer *buf)
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
void free_key_ctx(struct key_ctx *ctx)
bool crypto_check_replay(struct crypto_options *opt, const struct packet_id_net *pin, const char *error_prefix, struct gc_arena *gc)
Check packet ID for replay, and perform replay administration.
static int buf_len(const struct buffer *buf)
void write_pem_key_file(const char *filename, const char *pem_name)
Generate a server key with enough randomness to fill a key struct and write to file.
#define TLS_CRYPT_TAG_SIZE
struct packet_id_send send
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 int...
static int packet_id_size(bool long_form)
#define CO_PACKET_ID_LONG_FORM
Bit-flag indicating whether to use OpenVPN's long packet ID format.
static void gc_free(struct gc_arena *a)
uint8_t cipher[MAX_CIPHER_KEY_LENGTH]
Key material for cipher operations.
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
int cipher_ctx_reset(cipher_ctx_t *ctx, const uint8_t *iv_buf)
Resets the given cipher context, setting the IV to the specified value.
static void xor_key2(struct key2 *key, const struct key2 *other)
Will produce key = key XOR other.
static void gc_init(struct gc_arena *a)
bool read_pem_key_file(struct buffer *key, const char *pem_name, const char *key_file, bool key_inline)
Read key material from a PEM encoded files into the key structure.
Container for bidirectional cipher and HMAC key material.
static char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
#define CO_IGNORE_PACKET_ID
Bit-flag indicating whether to ignore the packet ID of a received packet.
static int buf_read_u8(struct buffer *buf)
struct packet_id packet_id
Current packet ID state for both sending and receiving directions.
static int buf_forward_capacity(const struct buffer *buf)
hmac_ctx_t * hmac
Generic HMAC context.
unsigned int flags
Bit-flags determining behavior of security operation functions.
struct key keys[2]
Two unidirectional sets of key material.
struct buffer alloc_buf(size_t size)
enum tls_wrap_ctx::@17 mode
Control channel wrapping mode.
#define TLS_CRYPT_V2_CLIENT_KEY_LEN
struct key_ctx decrypt
cipher and/or HMAC contexts for receiving direction.
bool cleanup_key_ctx
opt.key_ctx_bi is owned by this context
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.
int hmac_ctx_size(hmac_ctx_t *ctx)
Security parameter state for processing data channel packets.
void tls_crypt_v2_write_server_key_file(const char *filename)
Generate a tls-crypt-v2 server key, and write to file.
static int cleanup(void **state)