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++)
100 struct key2 rengokeys;
103 rengokeys.
keys,
sizeof(rengokeys.
keys)))
110 session->tls_wrap_reneg.mode = TLS_WRAP_CRYPT;
111 session->tls_wrap_reneg.cleanup_key_ctx =
true;
113 session->tls_wrap_reneg.opt.pid_persist = NULL;
118 "TLS_WRAP_RENEG",
session->key_id);
120 if (
session->tls_wrap.mode == TLS_WRAP_CRYPT
121 ||
session->tls_wrap.mode == TLS_WRAP_AUTH)
126 const int key_direction =
session->opt->server ?
135 &kt,
"dynamic tls-crypt");
174 "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->
capacity, src->
offset,
223 static const char error_prefix[] =
"tls-crypt unwrap error";
322 const int key_direction = tls_server ?
327 msg(
M_FATAL,
"ERROR: --tls-crypt-v2 not supported");
330 "Control Channel Encryption");
335 struct buffer *wkc_buf,
const char *key_file,
342 key_file, key_inline))
344 msg(
M_FATAL,
"ERROR: invalid tls-crypt-v2 client key format");
350 msg(
M_FATAL,
"ERROR: not enough data in tls-crypt-v2 client key");
354 *original_key =
key2;
356 *wkc_buf = client_key;
361 const char *key_file,
bool key_inline)
364 struct buffer srv_key_buf;
366 buf_set_write(&srv_key_buf, (
void *)&srv_key,
sizeof(srv_key));
368 key_file, key_inline))
370 msg(
M_FATAL,
"ERROR: invalid tls-crypt-v2 server key format");
376 msg(
M_FATAL,
"ERROR: --tls-crypt-v2 not supported");
388 const struct key2 *src_key,
389 const struct buffer *src_metadata,
400 msg(
M_WARN,
"ERROR: could not write tag");
403 uint16_t net_len = htons(
sizeof(src_key->
keys) +
BLEN(src_metadata)
424 msg(
M_WARN,
"ERROR: could not crypt: insufficient space in dst");
431 (
void *)src_key->
keys,
sizeof(src_key->
keys)));
434 BPTR(src_metadata),
BLEN(src_metadata)));
445 struct buffer wrapped_client_key,
448 const char *error_prefix = __func__;
455 struct buffer plaintext = { 0 };
459 BLEN(&wrapped_client_key),
468 uint16_t net_len = 0;
469 const uint8_t *tag =
BPTR(&wrapped_client_key);
471 if (
BLEN(&wrapped_client_key) <
sizeof(net_len))
475 memcpy(&net_len,
BEND(&wrapped_client_key) -
sizeof(net_len),
478 if (ntohs(net_len) !=
BLEN(&wrapped_client_key))
481 ntohs(net_len),
BLEN(&wrapped_client_key));
485 buf_inc_len(&wrapped_client_key, -(
int)
sizeof(net_len));
496 buf_set_write(&plaintext, plaintext_buf_data,
sizeof(plaintext_buf_data));
499 BPTR(&wrapped_client_key),
500 BLEN(&wrapped_client_key)))
528 "a different tls-crypt-v2 server key)");
531 if (
buf_len(&plaintext) <
sizeof(client_key->
keys))
535 memcpy(&client_key->
keys,
BPTR(&plaintext),
sizeof(client_key->
keys));
539 if (!
buf_copy(metadata, &plaintext))
541 CRYPT_ERROR(
"metadata too large for supplied buffer");
561 const char *tmp_file = NULL;
564 if (metadata_type < 0)
574 msg(
M_WARN,
"ERROR: could not write metadata to file");
578 char metadata_type_str[4] = { 0 };
579 snprintf(metadata_type_str,
sizeof(metadata_type_str),
580 "%i", (uint8_t) metadata_type);
597 msg(
M_WARN,
"WARNING: failed to remove temp file '%s", tmp_file);
622 "Client wants tls-crypt-v2, but no server key present.");
628 struct buffer wrapped_client_key = *buf;
629 uint16_t net_len = 0;
631 if (
BLEN(&wrapped_client_key) <
sizeof(net_len))
636 memcpy(&net_len,
BEND(&wrapped_client_key) -
sizeof(net_len),
639 uint16_t wkc_len = ntohs(net_len);
640 if (!
buf_advance(&wrapped_client_key,
BLEN(&wrapped_client_key) - wkc_len))
658 ctx->
mode = TLS_WRAP_CRYPT;
684 const char *b64_metadata,
685 const char *server_key_file,
686 bool server_key_inline)
689 struct key_ctx server_key = { 0 };
690 struct buffer client_key_pem = { 0 };
693 struct key2 client_key = { .
n = 2 };
697 msg(
M_FATAL,
"ERROR: could not generate random key");
705 size_t b64_length = strlen(b64_metadata);
712 msg(
M_FATAL,
"ERROR: failed to base64 decode provided metadata");
718 "ERROR: metadata too long (%d bytes, max %u bytes)",
727 int64_t timestamp =
htonll((uint64_t)
now);
737 msg(
M_FATAL,
"ERROR: could not wrap generated client key");
745 msg(
M_FATAL,
"ERROR: could not PEM-encode client key");
749 const char *client_file = filename;
750 bool client_inline =
false;
752 if (!filename ||
streq(filename,
""))
754 printf(
"%.*s\n",
BLEN(&client_key_pem),
BPTR(&client_key_pem));
755 client_file = (
const char *)
BPTR(&client_key_pem);
756 client_inline =
true;
760 msg(
M_FATAL,
"ERROR: could not write client key file");
766 struct buffer test_wrapped_client_key;
768 msg(
D_GENKEY,
"Testing client-side key loading...");
770 client_file, client_inline);
776 struct key2 test_client_key2 = { 0 };
780 msg(
D_GENKEY,
"Testing server-side key loading...");
782 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).
void init_key_ctx(struct key_ctx *ctx, const struct key_parameters *key, const struct key_type *kt, int enc, const char *prefix)
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
bool crypto_check_replay(struct crypto_options *opt, const struct packet_id_net *pin, uint16_t epoch, const char *error_prefix, struct gc_arena *gc)
Check packet ID for replay, and perform replay administration.
#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
#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.
enum tls_wrap_ctx::@23 mode
Control channel wrapping mode.
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.
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_session_generate_dynamic_tls_crypt_key(struct tls_session *session)
Generates a TLS-Crypt key to be used with dynamic tls-crypt using the TLS EKM exporter function.
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)
internal structure similar to struct key that holds key information but is not represented on wire an...
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.
Data structure for describing the packet id that is received/send to the network.
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)
void key_parameters_from_key(struct key_parameters *key_params, const struct key *key)
Converts a struct key representation into a struct key_parameters representation.
#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
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)