26 #elif defined(_MSC_VER) 59 msg(
M_WARN,
"ERROR: --tls-crypt requires AES-256-CTR support.");
64 msg(
M_WARN,
"ERROR: --tls-crypt requires HMAC-SHA-256 support.");
82 bool key_inline,
bool tls_server)
84 const int key_direction = tls_server ?
89 msg(
M_FATAL,
"ERROR: --tls-crypt not supported");
92 "Control Channel Encryption",
"tls-crypt");
100 msg(
D_MTU_DEBUG,
"%s: Adjusting frame parameters for tls-crypt by %i bytes",
137 "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->
capacity, src->
offset,
186 static const char error_prefix[] =
"tls-crypt unwrap error";
253 format_hex(tag_check,
sizeof(tag_check), 0, &gc));
285 const int key_direction = tls_server ?
290 msg(
M_FATAL,
"ERROR: --tls-crypt-v2 not supported");
293 "Control Channel Encryption");
298 const char *key_file,
bool key_inline)
304 key_file, key_inline))
306 msg(
M_FATAL,
"ERROR: invalid tls-crypt-v2 client key format");
312 msg(
M_FATAL,
"ERROR: not enough data in tls-crypt-v2 client key");
318 *wkc_buf = client_key;
323 const char *key_file,
bool key_inline)
326 struct buffer srv_key_buf;
328 buf_set_write(&srv_key_buf, (
void *)&srv_key,
sizeof(srv_key));
330 key_file, key_inline))
332 msg(
M_FATAL,
"ERROR: invalid tls-crypt-v2 server key format");
338 msg(
M_FATAL,
"ERROR: --tls-crypt-v2 not supported");
340 init_key_ctx(key_ctx, &srv_key, &kt, encrypt,
"tls-crypt-v2 server key");
346 const struct key2 *src_key,
347 const struct buffer *src_metadata,
358 msg(
M_WARN,
"ERROR: could not write tag");
382 msg(
M_WARN,
"ERROR: could not crypt: insufficient space in dst");
389 (
void *)src_key->
keys,
sizeof(src_key->
keys)));
392 BPTR(src_metadata),
BLEN(src_metadata)));
403 struct buffer wrapped_client_key,
406 const char *error_prefix = __func__;
413 struct buffer plaintext = { 0 };
417 BLEN(&wrapped_client_key),
429 if (
BLEN(&wrapped_client_key) <
sizeof(net_len))
433 memcpy(&net_len,
BEND(&wrapped_client_key) -
sizeof(net_len),
436 if (ntohs(net_len) !=
BLEN(&wrapped_client_key))
439 ntohs(net_len),
BLEN(&wrapped_client_key));
443 buf_inc_len(&wrapped_client_key, -(
int)
sizeof(net_len));
454 buf_set_write(&plaintext, plaintext_buf_data,
sizeof(plaintext_buf_data));
457 BPTR(&wrapped_client_key),
458 BLEN(&wrapped_client_key)))
483 format_hex(tag_check,
sizeof(tag_check), 0, &gc));
487 if (
buf_len(&plaintext) <
sizeof(client_key->
keys))
491 memcpy(&client_key->
keys,
BPTR(&plaintext),
sizeof(client_key->
keys));
494 if (!
buf_copy(metadata, &plaintext))
496 CRYPT_ERROR(
"metadata too large for supplied buffer");
516 const char *tmp_file = NULL;
519 if (metadata_type < 0)
529 msg(
M_WARN,
"ERROR: could not write metadata to file");
533 char metadata_type_str[4] = { 0 };
535 "%i", metadata_type);
537 setenv_str(es,
"script_type",
"tls-crypt-v2-verify");
538 setenv_str(es,
"metadata_type", metadata_type_str);
552 msg(
M_WARN,
"WARNING: failed to remove temp file '%s", tmp_file);
577 "Client wants tls-crypt-v2, but no server key present.");
583 struct buffer wrapped_client_key = *buf;
586 if (
BLEN(&wrapped_client_key) <
sizeof(net_len))
590 memcpy(&net_len,
BEND(&wrapped_client_key) -
sizeof(net_len),
593 size_t wkc_len = ntohs(net_len);
594 if (!
buf_advance(&wrapped_client_key,
BLEN(&wrapped_client_key) - wkc_len))
600 struct key2 client_key = { 0 };
613 ctx->
mode = TLS_WRAP_CRYPT;
639 const char *b64_metadata,
640 const char *server_key_file,
641 bool server_key_inline)
644 struct key_ctx server_key = { 0 };
645 struct buffer client_key_pem = { 0 };
648 struct key2 client_key = { 2 };
652 msg(
M_FATAL,
"ERROR: could not generate random key");
663 "ERROR: metadata too long (%d bytes, max %u bytes)",
671 msg(
M_FATAL,
"ERROR: failed to base64 decode provided metadata");
688 msg(
M_FATAL,
"ERROR: could not wrap generated client key");
696 msg(
M_FATAL,
"ERROR: could not PEM-encode client key");
700 const char *client_file = filename;
701 bool client_inline =
false;
703 if (!filename ||
streq(filename,
""))
705 printf(
"%.*s\n",
BLEN(&client_key_pem),
BPTR(&client_key_pem));
706 client_file = (
const char *)
BPTR(&client_key_pem);
707 client_inline =
true;
711 msg(
M_FATAL,
"ERROR: could not write client key file");
717 struct buffer test_wrapped_client_key;
718 msg(
D_GENKEY,
"Testing client-side key loading...");
720 client_file, client_inline);
726 struct key2 test_client_key2 = { 0 };
730 msg(
D_GENKEY,
"Testing server-side key loading...");
732 test_wrapped_client_key, &server_key));
const char * tls_crypt_v2_srv_pem_name
Security parameter state for processing data channel packets.
mbedtls_cipher_context_t cipher_ctx_t
Generic cipher context.
#define CO_PACKET_ID_LONG_FORM
Bit-flag indicating whether to use OpenVPN's long packet ID format.
#define CRYPT_ERROR(format)
struct env_set * env_set_create(struct gc_arena *gc)
struct packet_id packet_id
Current packet ID state for both sending and receiving directions.
void free_key_ctx(struct key_ctx *ctx)
uint8_t hmac_length
HMAC length, in bytes.
#define TLS_CRYPT_TAG_SIZE
void free_buf(struct buffer *buf)
unsigned int flags
Bit-flags determining behavior of security operation functions.
static int buf_len(const struct buffer *buf)
struct key keys[2]
Two unidirectional sets of key material.
struct buffer tls_crypt_v2_metadata
Received from client.
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
void init_key_ctx(struct key_ctx *ctx, const struct key *key, const struct key_type *kt, int enc, const char *prefix)
const char * tls_crypt_v2_verify_script
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
static bool buf_advance(struct buffer *buf, int size)
Packet geometry parameters.
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.
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.
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)
static void gc_free(struct gc_arena *a)
static void frame_add_to_extra_frame(struct frame *frame, const unsigned int increment)
static bool buf_safe(const struct buffer *buf, int len)
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 uint8_t * buf_write_alloc(struct buffer *buf, int size)
struct buffer alloc_buf(size_t size)
struct crypto_options opt
Crypto state.
#define TLS_CRYPT_OFF_TAG
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 char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
void setenv_str(struct env_set *es, const char *name, const char *value)
static int buf_read_u8(struct buffer *buf)
static void tls_crypt_v2_load_client_key(struct key_ctx_bi *key, const struct key2 *key2, bool tls_server)
#define TLS_CRYPT_V2_MAX_WKC_LEN
bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
static bool packet_id_initialized(const struct packet_id *pid)
Is this struct packet_id initialized?
#define TLS_CRYPT_BLOCK_SIZE
mbedtls_md_context_t hmac_ctx_t
Generic HMAC context.
int tls_crypt_buf_overhead(void)
Returns the maximum overhead (in bytes) added to the destination buffer by tls_crypt_wrap().
static bool buf_read(struct buffer *src, void *dest, int size)
int offset
Offset in bytes of the actual content within the allocated memory.
int capacity
Size in bytes of memory allocated by malloc().
int len
Length in bytes of the actual content within the allocated memory.
bool cleanup_key_ctx
opt.key_ctx_bi is owned by this context
static bool buf_write(struct buffer *dest, const void *src, int size)
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 KEY_DIRECTION_NORMAL
Control channel wrapping (–tls-auth/–tls-crypt) context.
void crypto_clear_error(void)
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
bool crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src, struct gc_arena *gc)
Encode binary data as PEM.
#define TLS_CRYPT_OFF_PID
static struct key_type tls_crypt_kt(void)
int rand_bytes(uint8_t *output, int len)
Wrapper for secure random number generator.
static struct gc_arena gc_new(void)
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).
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
static bool tls_crypt_v2_verify_metadata(const struct tls_wrap_ctx *ctx, const struct tls_options *opt)
uint8_t cipher_length
Cipher length, in bytes.
void hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
static void gc_init(struct gc_arena *a)
#define KEY_DIRECTION_INVERSE
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.
int openvpn_base64_decode(const char *str, void *data, int size)
cipher_ctx_t * cipher
Generic cipher context.
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.
void tls_crypt_v2_init_client_key(struct key_ctx_bi *key, struct buffer *wkc_buf, const char *key_file, bool key_inline)
Initialize a tls-crypt-v2 client key.
Container for one set of cipher and/or HMAC contexts.
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.
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
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 init_key_ctx_bi(struct key_ctx_bi *ctx, const struct key2 *key2, int key_direction, const struct key_type *kt, const char *name)
static int buf_forward_capacity(const struct buffer *buf)
int hmac_ctx_size(const hmac_ctx_t *ctx)
void buf_clear(struct buffer *buf)
const md_kt_t * md_kt_get(const char *digest)
Return message digest parameters, based on the given digest name.
static bool buf_copy(struct buffer *dest, const struct buffer *src)
hmac_ctx_t * hmac
Generic HMAC context.
void free_key_ctx_bi(struct key_ctx_bi *ctx)
#define CO_IGNORE_PACKET_ID
Bit-flag indicating whether to ignore the packet ID of a received packet.
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...
struct packet_id_send send
int cipher_kt_key_size(const cipher_kt_t *cipher_kt)
Returns the size of keys used by the cipher, in bytes.
#define TLS_CRYPT_V2_CLIENT_KEY_LEN
struct key_ctx decrypt
cipher and/or HMAC contexts for receiving direction.
void env_set_destroy(struct env_set *es)
unsigned __int64 uint64_t
Container for bidirectional cipher and HMAC key material.
void tls_crypt_adjust_frame_parameters(struct frame *frame)
Adjust frame parameters for –tls-crypt overhead.
unsigned char md_kt_size(const md_kt_t *kt)
Returns the size of the message digest, in bytes.
int cipher_ctx_block_size(const cipher_ctx_t *ctx)
Returns the block size of the cipher, in bytes.
static const uint8_t TLS_CRYPT_METADATA_TYPE_TIMESTAMP
Metadata contains a 64-bit unix timestamp in network byte order.
enum tls_wrap_ctx::@11 mode
Control channel wrapping mode.
static bool buf_inc_len(struct buffer *buf, int inc)
const md_kt_t * digest
Message digest static parameters.
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
#define TLS_CRYPT_V2_MAX_METADATA_LEN
Wrapper structure for dynamically allocated memory.
#define TLS_CRYPT_V2_MAX_B64_METADATA_LEN
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...
#define TLS_CRYPT_V2_TAG_SIZE
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
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).
unsigned __int16 uint16_t
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...
Garbage collection arena used to keep track of dynamically allocated memory.
void tls_crypt_v2_write_server_key_file(const char *filename)
Generate a tls-crypt-v2 server key, and write to file.
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)
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)
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
const char * tls_crypt_v2_cli_pem_name
void hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
const cipher_kt_t * cipher
Cipher static parameters.
void tls_crypt_init_key(struct key_ctx_bi *key, const char *key_file, bool key_inline, bool tls_server)
Initialize a key_ctx_bi structure for use with –tls-crypt.
struct key_ctx tls_crypt_v2_server_key
Decrypts client keys.
static int packet_id_size(bool long_form)
const cipher_kt_t * cipher_kt_get(const char *ciphername)
Return cipher parameters, based on the given cipher name.
void hmac_ctx_reset(hmac_ctx_t *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.
Container for two sets of OpenSSL cipher and/or HMAC contexts for both sending and receiving directio...
Container for unidirectional cipher and HMAC key material.
static const uint8_t TLS_CRYPT_METADATA_TYPE_USER
Metadata contains user-specified data.