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++)
101 session->tls_wrap_reneg.mode = TLS_WRAP_CRYPT;
102 session->tls_wrap_reneg.cleanup_key_ctx =
true;
104 session->tls_wrap_reneg.opt.pid_persist = NULL;
109 "TLS_WRAP_RENEG",
session->key_id);
112 struct key2 rengokeys;
115 rengokeys.
keys,
sizeof(rengokeys.
keys)))
121 if (
session->tls_wrap.mode == TLS_WRAP_CRYPT
122 ||
session->tls_wrap.mode == TLS_WRAP_AUTH)
127 const int key_direction =
session->opt->server ?
136 &kt,
"dynamic tls-crypt");
175 "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->
capacity, src->
offset,
224 static const char error_prefix[] =
"tls-crypt unwrap error";
323 const int key_direction = tls_server ?
328 msg(
M_FATAL,
"ERROR: --tls-crypt-v2 not supported");
331 "Control Channel Encryption");
336 struct buffer *wkc_buf,
const char *key_file,
345 msg(
M_FATAL,
"ERROR: invalid tls-crypt-v2 client key format");
351 msg(
M_FATAL,
"ERROR: not enough data in tls-crypt-v2 client key");
355 *original_key =
key2;
357 *wkc_buf = client_key;
362 const char *key_file,
bool key_inline)
371 msg(
M_FATAL,
"ERROR: invalid tls-crypt-v2 server key format");
377 msg(
M_FATAL,
"ERROR: --tls-crypt-v2 not supported");
389 const struct key2 *src_key,
390 const struct buffer *src_metadata,
401 msg(
M_WARN,
"ERROR: could not write tag");
425 msg(
M_WARN,
"ERROR: could not crypt: insufficient space in dst");
529 "a different tls-crypt-v2 server key)");
542 CRYPT_ERROR(
"metadata too large for supplied buffer");
562 const char *tmp_file = NULL;
575 msg(
M_WARN,
"ERROR: could not write metadata to file");
598 msg(
M_WARN,
"WARNING: failed to remove temp file '%s", tmp_file);
623 "Client wants tls-crypt-v2, but no server key present.");
659 ctx->
mode = TLS_WRAP_CRYPT;
690 struct key_ctx server_key = { 0 };
694 struct key2 client_key = { .
n = 2 };
698 msg(
M_FATAL,
"ERROR: could not generate random key");
713 msg(
M_FATAL,
"ERROR: failed to base64 decode provided metadata");
719 "ERROR: metadata too long (%d bytes, max %u bytes)",
738 msg(
M_FATAL,
"ERROR: could not wrap generated client key");
746 msg(
M_FATAL,
"ERROR: could not PEM-encode client key");
753 if (!filename ||
streq(filename,
""))
761 msg(
M_FATAL,
"ERROR: could not write client key file");
769 msg(
D_GENKEY,
"Testing client-side key loading...");
771 client_file, client_inline);
777 struct key2 test_client_key2 = { 0 };
781 msg(
D_GENKEY,
"Testing server-side key loading...");
783 test_wrapped_client_key, &server_key));
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 argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
#define OPENVPN_BASE64_DECODED_LENGTH(base64_length)
Compute the maximal number of bytes encoded in a base64 string.
void free_buf(struct buffer *buf)
void buf_clear(struct buffer *buf)
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
struct buffer alloc_buf(size_t size)
static char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
static bool buf_copy(struct buffer *dest, const struct buffer *src)
static bool buf_inc_len(struct buffer *buf, int inc)
static void gc_init(struct gc_arena *a)
static bool buf_safe(const struct buffer *buf, size_t len)
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
static bool buf_read(struct buffer *src, void *dest, int size)
static bool buf_advance(struct buffer *buf, int size)
static int buf_len(const struct buffer *buf)
static int buf_forward_capacity(const struct buffer *buf)
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
static bool buf_write(struct buffer *dest, const void *src, size_t size)
static int buf_read_u8(struct buffer *buf)
static void gc_free(struct gc_arena *a)
static struct gc_arena gc_new(void)
void free_key_ctx_bi(struct key_ctx_bi *ctx)
void init_key_ctx(struct key_ctx *ctx, const struct key_parameters *key, const struct key_type *kt, int enc, const char *prefix)
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.
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 key_parameters_from_key(struct key_parameters *key_params, const struct key *key)
Converts a struct key representation into a struct key_parameters representation.
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)
void key_direction_state_init(struct key_direction_state *kds, int key_direction)
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)
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.
void free_key_ctx(struct key_ctx *ctx)
Data Channel Cryptography Module.
#define KEY_DIRECTION_NORMAL
#define CO_PACKET_ID_LONG_FORM
Bit-flag indicating whether to use OpenVPN's long packet ID format.
#define CRYPT_ERROR(format)
#define CO_IGNORE_PACKET_ID
Bit-flag indicating whether to ignore the packet ID of a received packet.
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
#define KEY_DIRECTION_INVERSE
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.
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...
void hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
void hmac_ctx_reset(hmac_ctx_t *ctx)
int cipher_ctx_block_size(const cipher_ctx_t *ctx)
Returns the block size of the cipher, in bytes.
void hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
int hmac_ctx_size(hmac_ctx_t *ctx)
#define MAX_CIPHER_KEY_LENGTH
void crypto_clear_error(void)
int rand_bytes(uint8_t *output, int len)
Wrapper for secure random number generator.
#define MAX_HMAC_KEY_LENGTH
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.
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.
bool crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src, struct gc_arena *gc)
Encode binary data as PEM.
mbedtls_cipher_context_t cipher_ctx_t
Generic cipher context.
mbedtls_md_context_t hmac_ctx_t
Generic HMAC context.
void env_set_destroy(struct env_set *es)
void setenv_str(struct env_set *es, const char *name, const char *value)
struct env_set * env_set_create(struct gc_arena *gc)
#define TLS_CRYPT_V2_MAX_WKC_LEN
#define TLS_CRYPT_BLOCK_SIZE
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...
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.
#define TLS_CRYPT_TAG_SIZE
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 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.
#define TLS_CRYPT_OFF_PID
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).
#define TLS_CRYPT_OFF_TAG
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.
void tls_crypt_v2_write_server_key_file(const char *filename)
Generate a tls-crypt-v2 server key, and write to file.
int tls_crypt_buf_overhead(void)
Returns the maximum overhead (in bytes) added to the destination buffer by tls_crypt_wrap().
#define TLS_CRYPT_V2_CLIENT_KEY_LEN
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.
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).
#define TLS_CRYPT_V2_MAX_METADATA_LEN
#define TLS_CRYPT_V2_TAG_SIZE
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
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.
static bool packet_id_initialized(const struct packet_id *pid)
Is this struct packet_id initialized?
static int packet_id_size(bool long_form)
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.
int openvpn_base64_decode(const char *str, void *data, int size)
Control Channel SSL/Data channel negotiation module.
#define EXPORT_DYNAMIC_TLS_CRYPT_LABEL
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.
int capacity
Size in bytes of memory allocated by malloc().
int len
Length in bytes of the actual content within the allocated memory.
int offset
Offset in bytes of the actual content within the allocated memory.
Security parameter state for processing data channel packets.
unsigned int flags
Bit-flags determining behavior of security operation functions.
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
struct packet_id packet_id
Current packet ID state for both sending and receiving directions.
Garbage collection arena used to keep track of dynamically allocated memory.
Container for bidirectional cipher and HMAC key material.
int n
The number of key objects stored in the key2.keys array.
struct key keys[2]
Two unidirectional sets of key material.
Container for two sets of OpenSSL cipher and/or HMAC contexts for both sending and receiving directio...
struct key_ctx decrypt
cipher and/or HMAC contexts for receiving direction.
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
Container for one set of cipher and/or HMAC contexts.
cipher_ctx_t * cipher
Generic cipher context.
hmac_ctx_t * hmac
Generic HMAC context.
Key ordering of the key2.keys array.
internal structure similar to struct key that holds key information but is not represented on wire an...
const char * cipher
const name of the cipher
const char * digest
Message digest static parameters.
Container for unidirectional cipher and HMAC key material.
uint8_t cipher[MAX_CIPHER_KEY_LENGTH]
Key material for cipher operations.
uint8_t hmac[MAX_HMAC_KEY_LENGTH]
Key material for HMAC operations.
Data structure for describing the packet id that is received/send to the network.
struct packet_id_send send
const char * tls_crypt_v2_verify_script
Security parameter state of a single session within a VPN tunnel.
Control channel wrapping (–tls-auth/–tls-crypt) context.
struct buffer tls_crypt_v2_metadata
Received from client.
bool cleanup_key_ctx
opt.key_ctx_bi is owned by this context
struct crypto_options opt
Crypto state.
struct key_ctx tls_crypt_v2_server_key
Decrypts client keys.
enum tls_wrap_ctx::@23 mode
Control channel wrapping mode.
struct key2 original_wrap_keydata
original key data to be xored in to the key for dynamic tls-crypt.
static int cleanup(void **state)
static const char * test_client_key
static const uint8_t TLS_CRYPT_METADATA_TYPE_USER
Metadata contains user-specified data.
const char * tls_crypt_v2_srv_pem_name
static bool tls_crypt_v2_verify_metadata(const struct tls_wrap_ctx *ctx, const struct tls_options *opt)
static void tls_crypt_v2_load_client_key(struct key_ctx_bi *key, const struct key2 *key2, bool tls_server)
const char * tls_crypt_v2_cli_pem_name
static const uint8_t TLS_CRYPT_METADATA_TYPE_TIMESTAMP
Metadata contains a 64-bit unix timestamp in network byte order.
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 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)
static void xor_key2(struct key2 *key, const struct key2 *other)
Will produce key = key XOR other.
static struct key_type tls_crypt_kt(void)