OpenVPN
Macros | Functions | Variables
crypto.c File Reference
#include "syshead.h"
#include <string.h>
#include "crypto.h"
#include "error.h"
#include "integer.h"
#include "platform.h"
#include "memdbg.h"
Include dependency graph for crypto.c:

Go to the source code of this file.

Macros

#define PARSE_INITIAL   0
 
#define PARSE_HEAD   1
 
#define PARSE_DATA   2
 
#define PARSE_DATA_COMPLETE   3
 
#define PARSE_FOOT   4
 
#define PARSE_FINISHED   5
 

Functions

static void openvpn_encrypt_aead (struct buffer *buf, struct buffer work, struct crypto_options *opt)
 
static void openvpn_encrypt_v1 (struct buffer *buf, struct buffer work, struct crypto_options *opt)
 
void openvpn_encrypt (struct buffer *buf, struct buffer work, struct crypto_options *opt)
 Encrypt and HMAC sign a packet so that it can be sent as a data channel VPN tunnel packet to a remote OpenVPN peer. More...
 
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. More...
 
static bool openvpn_decrypt_aead (struct buffer *buf, struct buffer work, struct crypto_options *opt, const struct frame *frame, const uint8_t *ad_start)
 Unwrap (authenticate, decrypt and check replay protection) AEAD-mode data channel packets. More...
 
static bool openvpn_decrypt_v1 (struct buffer *buf, struct buffer work, struct crypto_options *opt, const struct frame *frame)
 
bool openvpn_decrypt (struct buffer *buf, struct buffer work, struct crypto_options *opt, const struct frame *frame, const uint8_t *ad_start)
 HMAC verify and decrypt a data channel packet received from a remote OpenVPN peer. More...
 
unsigned int calculate_crypto_overhead (const struct key_type *kt, unsigned int pkt_id_size, bool occ)
 Calculate the maximum overhead that our encryption has on a packet. More...
 
unsigned int crypto_max_overhead (void)
 Return the worst-case OpenVPN crypto overhead (in bytes) More...
 
static void warn_insecure_key_type (const char *ciphername)
 
void init_key_type (struct key_type *kt, const char *ciphername, const char *authname, bool tls_mode, bool warn)
 Initialize a key_type structure with. More...
 
void init_key_ctx (struct key_ctx *ctx, const struct key *key, const struct key_type *kt, int enc, const char *prefix)
 
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 free_key_ctx (struct key_ctx *ctx)
 
void free_key_ctx_bi (struct key_ctx_bi *ctx)
 
static bool key_is_zero (struct key *key, const struct key_type *kt)
 
bool check_key (struct key *key, const struct key_type *kt)
 
static void generate_key_random (struct key *key)
 
static void key_print (const struct key *key, const struct key_type *kt, const char *prefix)
 
void key2_print (const struct key2 *k, const struct key_type *kt, const char *prefix0, const char *prefix1)
 Prints the keys in a key2 structure. More...
 
void test_crypto (struct crypto_options *co, struct frame *frame)
 
const char * print_key_filename (const char *str, bool is_inline)
 To be used when printing a string that may contain inline data. More...
 
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 read_key_file (struct key2 *key2, const char *file, const unsigned int flags)
 
int write_key_file (const int nkeys, const char *filename)
 Write nkeys 1024-bits keys to file. More...
 
void must_have_n_keys (const char *filename, const char *option, const struct key2 *key2, int n)
 
int ascii2keydirection (int msglevel, const char *str)
 
const char * keydirection2ascii (int kd, bool remote, bool humanreadable)
 
void key_direction_state_init (struct key_direction_state *kds, int key_direction)
 
void verify_fix_key2 (struct key2 *key2, const struct key_type *kt, const char *shared_secret_file)
 
bool write_key (const struct key *key, const struct key_type *kt, struct buffer *buf)
 
int read_key (struct key *key, const struct key_type *kt, struct buffer *buf)
 
void prng_bytes (uint8_t *output, int len)
 
long int get_random (void)
 
void print_cipher (const char *ciphername)
 Print a cipher list entry. More...
 
static const cipher_name_pairget_cipher_name_pair (const char *cipher_name)
 
const char * translate_cipher_name_from_openvpn (const char *cipher_name)
 Translate an OpenVPN cipher name to a crypto library cipher name. More...
 
const char * translate_cipher_name_to_openvpn (const char *cipher_name)
 Translate a crypto library cipher name to an OpenVPN cipher name. More...
 
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. More...
 
bool generate_ephemeral_key (struct buffer *key, const char *key_name)
 Generate ephermal key material into the key structure. More...
 
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. More...
 
bool check_tls_prf_working (void)
 Checks if the current TLS library supports the TLS 1.0 PRF with MD5+SHA1 that OpenVPN uses when TLS Keying Material Export is not available. More...
 

Variables

static const char static_key_head [] = "-----BEGIN OpenVPN Static key V1-----"
 
static const char static_key_foot [] = "-----END OpenVPN Static key V1-----"
 
static const char printable_char_fmt []
 
static const char unprintable_char_fmt []
 

Macro Definition Documentation

◆ PARSE_DATA

#define PARSE_DATA   2

◆ PARSE_DATA_COMPLETE

#define PARSE_DATA_COMPLETE   3

◆ PARSE_FINISHED

#define PARSE_FINISHED   5

◆ PARSE_FOOT

#define PARSE_FOOT   4

◆ PARSE_HEAD

#define PARSE_HEAD   1

◆ PARSE_INITIAL

#define PARSE_INITIAL   0

Function Documentation

◆ ascii2keydirection()

int ascii2keydirection ( int  msglevel,
const char *  str 
)

Definition at line 1426 of file crypto.c.

References KEY_DIRECTION_BIDIRECTIONAL, KEY_DIRECTION_INVERSE, KEY_DIRECTION_NORMAL, and msg.

Referenced by add_option().

◆ calculate_crypto_overhead()

unsigned int calculate_crypto_overhead ( const struct key_type kt,
unsigned int  pkt_id_size,
bool  occ 
)

Calculate the maximum overhead that our encryption has on a packet.

This does not include needed additional buffer size

This does NOT include the padding and rounding of CBC size as the users (mssfix/fragment) of this function need to adjust for this and add it themselves.

Parameters
ktStruct with the crypto algorithm to use
packet_id_sizeSize of the packet id
occif true calculates the overhead for crypto in the same incorrect way as all previous OpenVPN versions did, to end up with identical numbers for OCC compatibility

Definition at line 670 of file crypto.c.

References key_type::cipher, cipher_defined(), cipher_kt_block_size(), cipher_kt_iv_size(), cipher_kt_mode_aead(), cipher_kt_mode_cbc(), cipher_kt_tag_size(), key_type::digest, md_defined(), and md_kt_size().

Referenced by frame_calculate_protocol_header_size().

◆ check_key()

bool check_key ( struct key key,
const struct key_type kt 
)

Definition at line 931 of file crypto.c.

References key_type::cipher, cipher_defined(), and key_is_zero().

Referenced by generate_key_expansion(), and verify_fix_key2().

◆ check_tls_prf_working()

bool check_tls_prf_working ( void  )

Checks if the current TLS library supports the TLS 1.0 PRF with MD5+SHA1 that OpenVPN uses when TLS Keying Material Export is not available.

Returns
true if supported, false otherwise.

Definition at line 1795 of file crypto.c.

References ssl_tls1_PRF().

Referenced by options_process_mutate_prf().

◆ crypto_check_replay()

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.

Parameters
optCrypto options for this packet, contains replay state.
pinPacket ID read from packet.
error_prefixPrefix to use when printing error messages.
gcGarbage collector to use.
Returns
true if packet ID is validated to be not a replay, false otherwise.

Definition at line 312 of file crypto.c.

References CO_MUTE_REPLAY_WARNINGS, CO_PACKET_ID_LONG_FORM, D_REPLAY_ERRORS, crypto_options::flags, msg, crypto_options::packet_id, packet_id_add(), packet_id_net_print(), packet_id_persist_save_obj(), packet_id_reap_test(), packet_id_test(), crypto_options::pid_persist, and packet_id::rec.

Referenced by openvpn_decrypt_aead(), openvpn_decrypt_v1(), and tls_crypt_unwrap().

◆ crypto_max_overhead()

unsigned int crypto_max_overhead ( void  )

Return the worst-case OpenVPN crypto overhead (in bytes)

Definition at line 719 of file crypto.c.

References max_int(), OPENVPN_AEAD_TAG_LENGTH, OPENVPN_MAX_CIPHER_BLOCK_SIZE, OPENVPN_MAX_HMAC_SIZE, OPENVPN_MAX_IV_LENGTH, and packet_id_size().

Referenced by frame_finalize_options().

◆ crypto_read_openvpn_key()

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 
)

◆ free_key_ctx()

void free_key_ctx ( struct key_ctx ctx)

◆ free_key_ctx_bi()

void free_key_ctx_bi ( struct key_ctx_bi ctx)

◆ generate_ephemeral_key()

bool generate_ephemeral_key ( struct buffer key,
const char *  pem_name 
)

Generate ephermal key material into the key structure.

Parameters
keythe key structure that will hold the key material
pem_namethe name used for logging
Returns
true if key generation was successful

Definition at line 1738 of file crypto.c.

References BCAP, BEND, buf_inc_len(), buffer::len, M_INFO, M_WARN, msg, and rand_bytes().

Referenced by auth_token_init_secret().

◆ generate_key_random()

static void generate_key_random ( struct key key)
static

◆ get_cipher_name_pair()

static const cipher_name_pair* get_cipher_name_pair ( const char *  cipher_name)
static

◆ get_random()

long int get_random ( void  )

◆ init_key_ctx()

void init_key_ctx ( struct key_ctx ctx,
const struct key key,
const struct key_type kt,
int  enc,
const char *  prefix 
)

◆ init_key_ctx_bi()

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 
)

◆ init_key_type()

void init_key_type ( struct key_type kt,
const char *  ciphername,
const char *  authname,
bool  tls_mode,
bool  warn 
)

Initialize a key_type structure with.

Parameters
ktThe struct key_type to initialize
ciphernameThe name of the cipher to use
authnameThe name of the HMAC digest to use
tls_modeSpecifies whether we are running in TLS mode, which allows more ciphers than static key mode.
warnPrint warnings when null cipher / auth is used.

Definition at line 744 of file crypto.c.

References ASSERT, key_type::cipher, cipher_kt_block_size(), cipher_kt_mode_aead(), cipher_kt_mode_cbc(), cipher_kt_mode_ofb_cfb(), cipher_valid(), CLEAR, key_type::digest, ENABLE_OFB_CFB_MODE, M_FATAL, M_WARN, md_kt_size(), msg, OPENVPN_MAX_CIPHER_BLOCK_SIZE, OPENVPN_MAX_HMAC_SIZE, and warn_insecure_key_type().

Referenced by calc_options_string_link_mtu(), do_init_crypto_none(), do_init_crypto_static(), do_init_crypto_tls_c1(), init_tas_auth(), options_string(), test_mssfix_mtu_calculation(), and tls_session_update_crypto_params_do_work().

◆ key2_print()

void key2_print ( const struct key2 k,
const struct key_type kt,
const char *  prefix0,
const char *  prefix1 
)

Prints the keys in a key2 structure.

Definition at line 988 of file crypto.c.

References ASSERT, key_print(), key2::keys, and key2::n.

Referenced by generate_key_expansion().

◆ key_direction_state_init()

void key_direction_state_init ( struct key_direction_state kds,
int  key_direction 
)

◆ key_is_zero()

static bool key_is_zero ( struct key key,
const struct key_type kt 
)
static

Definition at line 913 of file crypto.c.

References key_type::cipher, key::cipher, cipher_kt_key_size(), D_CRYPT_ERRORS, and msg.

Referenced by check_key().

◆ key_print()

static void key_print ( const struct key key,
const struct key_type kt,
const char *  prefix 
)
static

◆ keydirection2ascii()

const char* keydirection2ascii ( int  kd,
bool  remote,
bool  humanreadable 
)

◆ must_have_n_keys()

void must_have_n_keys ( const char *  filename,
const char *  option,
const struct key2 key2,
int  n 
)

Definition at line 1413 of file crypto.c.

References M_FATAL, msg, key2::n, and PACKAGE.

Referenced by crypto_read_openvpn_key().

◆ openvpn_decrypt_aead()

static bool openvpn_decrypt_aead ( struct buffer buf,
struct buffer  work,
struct crypto_options opt,
const struct frame frame,
const uint8_t *  ad_start 
)
static

◆ openvpn_decrypt_v1()

static bool openvpn_decrypt_v1 ( struct buffer buf,
struct buffer  work,
struct crypto_options opt,
const struct frame frame 
)
static

◆ openvpn_encrypt_aead()

static void openvpn_encrypt_aead ( struct buffer buf,
struct buffer  work,
struct crypto_options opt 
)
static

◆ openvpn_encrypt_v1()

static void openvpn_encrypt_v1 ( struct buffer buf,
struct buffer  work,
struct crypto_options opt 
)
static

◆ print_cipher()

void print_cipher ( const char *  ciphername)

Print a cipher list entry.

Definition at line 1623 of file crypto.c.

References cipher_kt_block_size(), cipher_kt_key_size(), cipher_kt_mode_cbc(), cipher_kt_name(), and cipher_valid_reason().

Referenced by show_available_ciphers().

◆ print_key_filename()

const char* print_key_filename ( const char *  str,
bool  is_inline 
)

To be used when printing a string that may contain inline data.

If "is_inline" is true, return the inline tag. If "is_inline" is false and "str" is not NULL, return "str". Return the constant string "[NULL]" otherwise.

Parameters
strthe original string to return when is_inline is false
is_inlinetrue when str contains an inline data of some sort

Definition at line 1083 of file crypto.c.

References np().

Referenced by backend_tls_ctx_reload_crl(), crypto_read_openvpn_key(), read_key_file(), tls_ctx_load_ca(), tls_ctx_load_dh_params(), tls_ctx_load_extra_certs(), and tls_ctx_load_priv_file().

◆ prng_bytes()

void prng_bytes ( uint8_t *  output,
int  len 
)

Definition at line 1604 of file crypto.c.

Referenced by get_random(), hostname_randomize(), openvpn_encrypt_v1(), and session_id_random().

◆ read_key()

int read_key ( struct key key,
const struct key_type kt,
struct buffer buf 
)

◆ read_key_file()

void read_key_file ( struct key2 key2,
const char *  file,
const unsigned int  flags 
)

◆ read_pem_key_file()

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.

Parameters
keythe key structure that will hold the key material
pem_namethe name used in the pem encoding start/end lines
key_filename of the file to read or the key itself if key_inline is true
key_inlineTrue if key_file contains an inline key, False otherwise.
Returns
true if reading into key was successful

Definition at line 1756 of file crypto.c.

References buf_clear(), buf_set_read(), buf_valid(), buffer_read_from_file(), cleanup(), crypto_pem_decode(), gc_free(), gc_new(), M_WARN, and msg.

Referenced by auth_token_init_secret(), tls_crypt_v2_init_client_key(), and tls_crypt_v2_init_server_key().

◆ test_crypto()

void test_crypto ( struct crypto_options co,
struct frame frame 
)

◆ translate_cipher_name_from_openvpn()

const char* translate_cipher_name_from_openvpn ( const char *  cipher_name)

Translate an OpenVPN cipher name to a crypto library cipher name.

Parameters
cipher_nameAn OpenVPN cipher name
Returns
The corresponding crypto library cipher name, or NULL if no matching cipher name was found.

Definition at line 1674 of file crypto.c.

References get_cipher_name_pair(), and cipher_name_pair::lib_name.

Referenced by cipher_get(), and cipher_kt_block_size().

◆ translate_cipher_name_to_openvpn()

const char* translate_cipher_name_to_openvpn ( const char *  cipher_name)

Translate a crypto library cipher name to an OpenVPN cipher name.

Parameters
cipher_nameA crypto library cipher name
Returns
The corresponding OpenVPN cipher name, or NULL if no matching cipher name was found.

Definition at line 1687 of file crypto.c.

References get_cipher_name_pair(), and cipher_name_pair::openvpn_name.

Referenced by cipher_kt_block_size(), cipher_kt_name(), and multi_print_status().

◆ verify_fix_key2()

void verify_fix_key2 ( struct key2 key2,
const struct key_type kt,
const char *  shared_secret_file 
)

Definition at line 1507 of file crypto.c.

References check_key(), key2::keys, M_FATAL, msg, and key2::n.

Referenced by crypto_read_openvpn_key().

◆ warn_insecure_key_type()

static void warn_insecure_key_type ( const char *  ciphername)
static

Definition at line 727 of file crypto.c.

References cipher_kt_block_size(), cipher_kt_insecure(), M_WARN, and msg.

Referenced by init_key_ctx(), and init_key_type().

◆ write_key()

bool write_key ( const struct key key,
const struct key_type kt,
struct buffer buf 
)

◆ write_key_file()

int write_key_file ( const int  nkeys,
const char *  filename 
)

Write nkeys 1024-bits keys to file.

Returns
number of random bits written, or -1 on failure.

Definition at line 1350 of file crypto.c.

References alloc_buf_gc(), BLEN, BPTR, buf_clear(), buf_printf(), buffer_write_file(), format_hex_ex(), gc_free(), gc_new(), generate_key_random(), secure_memzero(), static_key_foot, and static_key_head.

Referenced by do_genkey().

◆ write_pem_key_file()

void write_pem_key_file ( const char *  filename,
const char *  key_name 
)

Generate a server key with enough randomness to fill a key struct and write to file.

Parameters
filenameFilename of the server key file to create.
pem_nameThe name to use in the PEM header/footer.

Definition at line 1700 of file crypto.c.

References BLEN, BPTR, buf_clear(), buf_set_read(), buffer_write_file(), cleanup(), clear_buf(), crypto_pem_encode(), gc_free(), gc_new(), M_ERR, M_NONFATAL, M_WARN, msg, rand_bytes(), and secure_memzero().

Referenced by auth_token_write_server_key_file(), and tls_crypt_v2_write_server_key_file().

Variable Documentation

◆ printable_char_fmt

const char printable_char_fmt[]
static
Initial value:
=
"Non-Hex character ('%c') found at line %d in key file '%s' (%d/%d/%d bytes found/min/max)"

Definition at line 1137 of file crypto.c.

Referenced by read_key_file().

◆ static_key_foot

const char static_key_foot[] = "-----END OpenVPN Static key V1-----"
static

Definition at line 1135 of file crypto.c.

Referenced by read_key_file(), and write_key_file().

◆ static_key_head

const char static_key_head[] = "-----BEGIN OpenVPN Static key V1-----"
static

Definition at line 1134 of file crypto.c.

Referenced by read_key_file(), and write_key_file().

◆ unprintable_char_fmt

const char unprintable_char_fmt[]
static
Initial value:
=
"Non-Hex, unprintable character (0x%02x) found at line %d in key file '%s' (%d/%d/%d bytes found/min/max)"

Definition at line 1140 of file crypto.c.

Referenced by read_key_file().