6fbf66fa |
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
* |
49979459 |
* Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
* Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> |
6fbf66fa |
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* |
caa54ac3 |
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
6fbf66fa |
*/
|
7b51513e |
/** |
b5738e5b |
* @file Data Channel Cryptography Module |
b08c25db |
*
* @addtogroup data_crypto Data Channel Crypto module
*
* @par Crypto packet formats
* The Data Channel Crypto module supports a number of crypto modes and
* configurable options. The actual packet format depends on these options. A
* Data Channel packet can consist of:
* - \b Opcode, one byte specifying the packet type (see @ref network_protocol
* "Network protocol").
* - \b Peer-id, if using the v2 data channel packet format (see @ref
* network_protocol "Network protocol").
* - \b HMAC, covering the ciphertext IV + ciphertext. The HMAC size depends
* on the \c \-\-auth option. If \c \-\-auth \c none is specified, there is no
* HMAC at all. |
ef910e3e |
* - \b Ciphertext \b IV. The IV size depends on the \c \-\-cipher option. |
b08c25db |
* - \b Packet \b ID, a 32-bit incrementing packet counter that provides replay
* protection (if not disabled by \c \-\-no-replay).
* - \b Timestamp, a 32-bit timestamp of the current time.
* - \b Payload, the plain text network packet to be encrypted (unless
* encryption is disabled by using \c \-\-cipher \c none). The payload might
* already be compressed (see @ref compression "Compression module").
*
* @par
* This section does not discuss the opcode and peer-id, since those do not
* depend on the data channel crypto. See @ref network_protocol
* "Network protocol" for more information on those.
*
* @par
* \e Legenda \n
* <tt>[ xxx ]</tt> = unprotected \n
* <tt>[ - xxx - ]</tt> = authenticated \n
* <tt>[ * xxx * ]</tt> = encrypted and authenticated
*
* @par
* <b>CBC data channel cypto format</b> \n
* In CBC mode, both TLS-mode and static key mode are supported. The IV
* consists of random bits to provide unpredictable IVs. \n
* <i>CBC IV format:</i> \n
* <tt> [ - random - ] </tt> \n
* <i>CBC data channel crypto format in TLS-mode:</i> \n
* <tt> [ HMAC ] [ - IV - ] [ * packet ID * ] [ * packet payload * ] </tt> \n
* <i>CBC data channel crypto format in static key mode:</i> \n
* <tt> [ HMAC ] [ - IV - ] [ * packet ID * ] [ * timestamp * ]
* [ * packet payload * ] </tt>
*
* @par
* <b>CFB/OFB data channel crypto format</b> \n
* CFB and OFB modes are only supported in TLS mode. In these modes, the IV
* consists of the packet counter and a timestamp. If the IV is more than 8
* bytes long, the remaining space is filled with zeroes. The packet counter may
* not roll over within a single TLS sessions. This results in a unique IV for
* each packet, as required by the CFB and OFB cipher modes.
*
* @par
* <i>CFB/OFB IV format:</i> \n
* <tt> [ - packet ID - ] [ - timestamp - ] [ - opt: zero-padding - ] </tt>\n
* <i>CFB/OFB data channel crypto format:</i> \n
* <tt> [ HMAC ] [ - IV - ] [ * packet payload * ] </tt>
*
* @par |
66407e11 |
* <b>GCM data channel crypto format</b> \n
* GCM modes are only supported in TLS mode. In these modes, the IV consists of
* the 32-bit packet counter followed by data from the HMAC key. The HMAC key
* can be used as IV, since in GCM and CCM modes the HMAC key is not used for
* the HMAC. The packet counter may not roll over within a single TLS sessions.
* This results in a unique IV for each packet, as required by GCM.
*
* @par
* The HMAC key data is pre-shared during the connection setup, and thus can be
* omitted in on-the-wire packets, saving 8 bytes per packet (for GCM and CCM).
*
* @par
* In GCM mode, P_DATA_V2 headers (the opcode and peer-id) are also
* authenticated as Additional Data.
*
* @par
* <i>GCM IV format:</i> \n
* <tt> [ - packet ID - ] [ - HMAC key data - ] </tt>\n
* <i>P_DATA_V1 GCM data channel crypto format:</i> \n
* <tt> [ opcode ] [ - packet ID - ] [ TAG ] [ * packet payload * ] </tt>
* <i>P_DATA_V2 GCM data channel crypto format:</i> \n
* <tt> [ - opcode/peer-id - ] [ - packet ID - ] [ TAG ] [ * packet payload * ] </tt>
*
* @par |
b08c25db |
* <b>No-crypto data channel format</b> \n
* In no-crypto mode (\c \-\-cipher \c none is specified), both TLS-mode and
* static key mode are supported. No encryption will be performed on the packet,
* but packets can still be authenticated. This mode does not require an IV.\n
* <i>No-crypto data channel crypto format in TLS-mode:</i> \n
* <tt> [ HMAC ] [ - packet ID - ] [ - packet payload - ] </tt> \n
* <i>No-crypto data channel crypto format in static key mode:</i> \n
* <tt> [ HMAC ] [ - packet ID - ] [ - timestamp - ] [ - packet payload - ] </tt>
* |
7b51513e |
*/
|
6fbf66fa |
#ifndef CRYPTO_H
#define CRYPTO_H |
b5738e5b |
#include "crypto_backend.h" |
6fbf66fa |
#include "basic.h"
#include "buffer.h"
#include "packet_id.h"
#include "mtu.h"
|
5b48e8c9 |
/** Wrapper struct to pass around SHA256 digests */
struct sha256_digest {
uint8_t digest[SHA256_DIGEST_LENGTH]; |
2dd6501e |
};
|
6fbf66fa |
/*
* Defines a key type and key length for both cipher and HMAC.
*/
struct key_type
{ |
81d882d5 |
uint8_t cipher_length; /**< Cipher length, in bytes */
uint8_t hmac_length; /**< HMAC length, in bytes */
const cipher_kt_t *cipher; /**< Cipher static parameters */
const md_kt_t *digest; /**< Message digest static parameters */ |
6fbf66fa |
};
|
7b51513e |
/**
* Container for unidirectional cipher and HMAC %key material.
* @ingroup control_processor |
6fbf66fa |
*/
struct key
{ |
81d882d5 |
uint8_t cipher[MAX_CIPHER_KEY_LENGTH];
/**< %Key material for cipher operations. */
uint8_t hmac[MAX_HMAC_KEY_LENGTH];
/**< %Key material for HMAC operations. */ |
6fbf66fa |
};
|
485c5f76 |
/** |
66407e11 |
* Container for one set of cipher and/or HMAC contexts. |
485c5f76 |
* @ingroup control_processor
*/
struct key_ctx
{ |
81d882d5 |
cipher_ctx_t *cipher; /**< Generic cipher %context. */
hmac_ctx_t *hmac; /**< Generic HMAC %context. */
uint8_t implicit_iv[OPENVPN_MAX_IV_LENGTH];
/**< The implicit part of the IV */
size_t implicit_iv_len; /**< The length of implicit_iv */ |
485c5f76 |
};
|
6fbf66fa |
#define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */
#define KEY_DIRECTION_NORMAL 1 /* encrypt with keys[0], decrypt with keys[1] */
#define KEY_DIRECTION_INVERSE 2 /* encrypt with keys[1], decrypt with keys[0] */
|
7b51513e |
/**
* Container for bidirectional cipher and HMAC %key material.
* @ingroup control_processor |
6fbf66fa |
*/
struct key2
{ |
81d882d5 |
int n; /**< The number of \c key objects stored |
7b51513e |
* in the \c key2.keys array. */ |
81d882d5 |
struct key keys[2]; /**< Two unidirectional sets of %key |
7b51513e |
* material. */ |
6fbf66fa |
};
|
7b51513e |
/**
* %Key ordering of the \c key2.keys array.
* @ingroup control_processor
*
* This structure takes care of correct ordering when using unidirectional
* or bidirectional %key material, and allows the same shared secret %key
* file to be loaded in the same way by client and server by having one of
* the hosts use an reversed ordering. |
6fbf66fa |
*/
struct key_direction_state
{ |
81d882d5 |
int out_key; /**< Index into the \c key2.keys array for |
7b51513e |
* the sending direction. */ |
81d882d5 |
int in_key; /**< Index into the \c key2.keys array for |
7b51513e |
* the receiving direction. */ |
81d882d5 |
int need_keys; /**< The number of key objects necessary |
7b51513e |
* to support both sending and
* receiving.
*
* This will be 1 if the same keys are
* used in both directions, or 2 if
* there are two sets of unidirectional
* keys. */ |
6fbf66fa |
};
|
7b51513e |
/**
* Container for two sets of OpenSSL cipher and/or HMAC contexts for both
* sending and receiving directions.
* @ingroup control_processor |
6fbf66fa |
*/
struct key_ctx_bi
{ |
81d882d5 |
struct key_ctx encrypt; /**< Cipher and/or HMAC contexts for sending
* direction. */
struct key_ctx decrypt; /**< cipher and/or HMAC contexts for |
66407e11 |
* receiving direction. */ |
81d882d5 |
bool initialized; |
6fbf66fa |
};
|
7b51513e |
/**
* Security parameter state for processing data channel packets.
* @ingroup data_crypto |
6fbf66fa |
*/
struct crypto_options
{ |
81d882d5 |
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 |
7b51513e |
* sending and receiving directions. */ |
81d882d5 |
struct packet_id_persist *pid_persist;
/**< Persistent packet ID state for
* keeping state between successive
* OpenVPN process startups. */
#define CO_PACKET_ID_LONG_FORM (1<<0)
/**< Bit-flag indicating whether to use
* OpenVPN's long packet ID format. */ |
ef910e3e |
#define CO_IGNORE_PACKET_ID (1<<1) |
81d882d5 |
/**< Bit-flag indicating whether to ignore
* the packet ID of a received packet.
* This flag is used during processing
* of the first packet received from a
* client. */ |
ef910e3e |
#define CO_MUTE_REPLAY_WARNINGS (1<<2) |
81d882d5 |
/**< Bit-flag indicating not to display
* replay warnings. */
unsigned int flags; /**< Bit-flags determining behavior of |
7b51513e |
* security operation functions. */ |
6fbf66fa |
};
|
c6e24fa3 |
#define CRYPT_ERROR(format) \ |
81d882d5 |
do { msg(D_CRYPT_ERRORS, "%s: " format, error_prefix); goto error_exit; } while (false) |
c6e24fa3 |
|
66407e11 |
/**
* Minimal IV length for AEAD mode ciphers (in bytes):
* 4-byte packet id + 8 bytes implicit IV.
*/ |
81d882d5 |
#define OPENVPN_AEAD_MIN_IV_LEN (sizeof(packet_id_type) + 8) |
66407e11 |
|
c959fc74 |
#define RKF_MUST_SUCCEED (1<<0)
#define RKF_INLINE (1<<1) |
81d882d5 |
void read_key_file(struct key2 *key2, const char *file, const unsigned int flags); |
6fbf66fa |
|
81d882d5 |
int write_key_file(const int nkeys, const char *filename); |
6fbf66fa |
|
81d882d5 |
int read_passphrase_hash(const char *passphrase_file,
const md_kt_t *digest,
uint8_t *output,
int len); |
6fbf66fa |
|
81d882d5 |
void generate_key_random(struct key *key, const struct key_type *kt); |
6fbf66fa |
|
ef910e3e |
void check_replay_consistency(const struct key_type *kt, bool packet_id); |
6fbf66fa |
|
81d882d5 |
bool check_key(struct key *key, const struct key_type *kt); |
6fbf66fa |
|
81d882d5 |
void fixup_key(struct key *key, const struct key_type *kt); |
6fbf66fa |
|
81d882d5 |
bool write_key(const struct key *key, const struct key_type *kt,
struct buffer *buf); |
6fbf66fa |
|
81d882d5 |
int read_key(struct key *key, const struct key_type *kt, struct buffer *buf); |
6fbf66fa |
|
dea8917a |
/**
* Initialize a key_type structure with.
*
* @param kt The struct key_type to initialize
* @param ciphername The name of the cipher to use
* @param authname The name of the HMAC digest to use
* @param keysize The length of the cipher key to use, in bytes. Only valid
* for ciphers that support variable length keys.
* @param tls_mode Specifies wether we are running in TLS mode, which allows
* more ciphers than static key mode.
* @param warn Print warnings when null cipher / auth is used.
*/ |
81d882d5 |
void init_key_type(struct key_type *kt, const char *ciphername,
const char *authname, int keysize, bool tls_mode, bool warn); |
6fbf66fa |
|
902f674e |
/*
* Key context functions
*/ |
6fbf66fa |
|
5e6e4b7d |
void init_key_ctx(struct key_ctx *ctx, const struct key *key, |
81d882d5 |
const struct key_type *kt, int enc,
const char *prefix); |
6fbf66fa |
|
81d882d5 |
void free_key_ctx(struct key_ctx *ctx); |
485c5f76 |
|
974513ea |
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);
|
81d882d5 |
void free_key_ctx_bi(struct key_ctx_bi *ctx); |
6fbf66fa |
|
7b51513e |
/**************************************************************************/
/** @name Functions for performing security operations on data channel packets
* @{ */
/**
* Encrypt and HMAC sign a packet so that it can be sent as a data channel
* VPN tunnel packet to a remote OpenVPN peer.
* @ingroup data_crypto
*
* This function handles encryption and HMAC signing of a data channel
* packet before it is sent to its remote OpenVPN peer. It receives the
* necessary security parameters in the \a opt argument, which should have
* been set to the correct values by the \c tls_pre_encrypt() function.
*
* This function calls the \c EVP_Cipher* and \c HMAC_* functions of the
* OpenSSL library to perform the actual security operations.
*
* If an error occurs during processing, then the \a buf %buffer is set to
* empty.
*
* @param buf - The %buffer containing the packet on which to
* perform security operations. |
66407e11 |
* @param work - An initialized working %buffer. |
7b51513e |
* @param opt - The security parameter state for this VPN tunnel. |
66407e11 |
* |
7b51513e |
* @return This function returns void.\n On return, the \a buf argument
* will point to the resulting %buffer. This %buffer will either
* contain the processed packet ready for sending, or be empty if an
* error occurred.
*/ |
81d882d5 |
void openvpn_encrypt(struct buffer *buf, struct buffer work,
struct crypto_options *opt); |
6fbf66fa |
|
7b51513e |
/**
* HMAC verify and decrypt a data channel packet received from a remote
* OpenVPN peer.
* @ingroup data_crypto
*
* This function handles authenticating and decrypting a data channel
* packet received from a remote OpenVPN peer. It receives the necessary
* security parameters in the \a opt argument, which should have been set
* to the correct values by the \c tls_pre_decrypt() function.
*
* This function calls the \c EVP_Cipher* and \c HMAC_* functions of the
* OpenSSL library to perform the actual security operations.
*
* If an error occurs during processing, then the \a buf %buffer is set to
* empty.
*
* @param buf - The %buffer containing the packet received from a
* remote OpenVPN peer on which to perform security
* operations.
* @param work - A working %buffer.
* @param opt - The security parameter state for this VPN tunnel.
* @param frame - The packet geometry parameters for this VPN
* tunnel. |
66407e11 |
* @param ad_start - A pointer into buf, indicating from where to start
* authenticating additional data (AEAD mode only). |
7b51513e |
*
* @return
* @li True, if the packet was authenticated and decrypted successfully.
* @li False, if an error occurred. \n On return, the \a buf argument will
* point to the resulting %buffer. This %buffer will either contain
* the plaintext packet ready for further processing, or be empty if
* an error occurred.
*/ |
81d882d5 |
bool openvpn_decrypt(struct buffer *buf, struct buffer work,
struct crypto_options *opt, const struct frame *frame,
const uint8_t *ad_start); |
6fbf66fa |
|
7b51513e |
/** @} name Functions for performing security operations on data channel packets */
|
c6e24fa3 |
/**
* Check packet ID for replay, and perform replay administration.
* |
81d882d5 |
* @param opt Crypto options for this packet, contains replay state.
* @param pin Packet ID read from packet.
* @param error_prefix Prefix to use when printing error messages.
* @param gc Garbage collector to use. |
c6e24fa3 |
*
* @return true if packet ID is validated to be not a replay, false otherwise.
*/
bool crypto_check_replay(struct crypto_options *opt, |
81d882d5 |
const struct packet_id_net *pin, const char *error_prefix,
struct gc_arena *gc); |
c6e24fa3 |
|
97894360 |
/** Calculate crypto overhead and adjust frame to account for that */ |
6fbf66fa |
void crypto_adjust_frame_parameters(struct frame *frame, |
81d882d5 |
const struct key_type *kt,
bool packet_id,
bool packet_id_long_form); |
6fbf66fa |
|
97894360 |
/** Return the worst-case OpenVPN crypto overhead (in bytes) */
size_t crypto_max_overhead(void); |
279a308e |
/* Minimum length of the nonce used by the PRNG */ |
03bfb228 |
#define NONCE_SECRET_LEN_MIN 16 |
279a308e |
/* Maximum length of the nonce used by the PRNG */ |
03bfb228 |
#define NONCE_SECRET_LEN_MAX 64 |
279a308e |
|
557624e0 |
/** Number of bytes of random to allow before resetting the nonce */
#define PRNG_NONCE_RESET_BYTES 1024
|
279a308e |
/**
* Pseudo-random number generator initialisation.
* (see \c prng_rand_bytes())
* |
81d882d5 |
* @param md_name Name of the message digest to use
* @param nonce_secret_len_param Length of the nonce to use |
279a308e |
*/ |
81d882d5 |
void prng_init(const char *md_name, const int nonce_secret_len_parm); |
279a308e |
/*
* Message digest-based pseudo random number generator.
*
* If the PRNG was initialised with a certain message digest, uses the digest
* to calculate the next random number, and prevent depletion of the entropy
* pool.
*
* This PRNG is aimed at IV generation and similar miscellaneous tasks. Use
* \c rand_bytes() for higher-assurance functionality.
*
* Retrieves len bytes of pseudo random data, and places it in output.
* |
81d882d5 |
* @param output Output buffer
* @param len Length of the output buffer |
279a308e |
*/ |
81d882d5 |
void prng_bytes(uint8_t *output, int len); |
279a308e |
|
e2a0cad4 |
void prng_uninit(void); |
6fbf66fa |
|
81d882d5 |
void test_crypto(struct crypto_options *co, struct frame *f); |
6fbf66fa |
/* key direction functions */
|
81d882d5 |
void key_direction_state_init(struct key_direction_state *kds, int key_direction); |
6fbf66fa |
|
81d882d5 |
void verify_fix_key2(struct key2 *key2, const struct key_type *kt, const char *shared_secret_file); |
6fbf66fa |
|
81d882d5 |
void must_have_n_keys(const char *filename, const char *option, const struct key2 *key2, int n); |
6fbf66fa |
|
81d882d5 |
int ascii2keydirection(int msglevel, const char *str); |
6fbf66fa |
|
81d882d5 |
const char *keydirection2ascii(int kd, bool remote); |
6fbf66fa |
/* print keys */ |
81d882d5 |
void key2_print(const struct key2 *k,
const struct key_type *kt,
const char *prefix0,
const char *prefix1); |
6fbf66fa |
|
81d882d5 |
void crypto_read_openvpn_key(const struct key_type *key_type,
struct key_ctx_bi *ctx, const char *key_file, const char *key_inline,
const int key_direction, const char *key_name, const char *opt_name); |
6fbf66fa |
/* |
76daface |
* Inline functions
*/
|
b891e57e |
/**
* As memcmp(), but constant-time.
* Returns 0 when data is equal, non-zero otherwise.
*/
static inline int |
4cd4899e |
memcmp_constant_time(const void *a, const void *b, size_t size)
{ |
81d882d5 |
const uint8_t *a1 = a;
const uint8_t *b1 = b;
int ret = 0;
size_t i; |
b891e57e |
|
81d882d5 |
for (i = 0; i < size; i++) {
ret |= *a1++ ^ *b1++;
} |
b891e57e |
|
81d882d5 |
return ret; |
b891e57e |
}
|
76daface |
static inline bool |
81d882d5 |
key_ctx_bi_defined(const struct key_ctx_bi *key) |
76daface |
{ |
81d882d5 |
return key->encrypt.cipher || key->encrypt.hmac || key->decrypt.cipher || key->decrypt.hmac; |
76daface |
}
|
6fbf66fa |
#endif /* CRYPTO_H */ |