46#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
47#include <openssl/core_names.h>
48#include <openssl/kdf.h>
51static const char testtext[] =
"Dummy text to test PEM encoding";
105 for (
int i = 0; i < strlen(ciphername); i++)
107 upper[i] = (char)toupper((
unsigned char)ciphername[i]);
108 lower[i] = (char)tolower((
unsigned char)ciphername[i]);
111 random_case[i] = upper[i];
115 random_case[i] = lower[i];
121 openvpn_name = upper;
147static const char *
ipsumlorem =
"Lorem ipsum dolor sit amet, consectetur "
148 "adipisici elit, sed eiusmod tempor incidunt "
149 "ut labore et dolore magna aliqua.";
154 const char *seedstr =
"Quis aute iure reprehenderit in voluptate "
155 "velit esse cillum dolore";
156 const unsigned char *seed = (
const unsigned char *)seedstr;
157 const size_t seed_len = strlen(seedstr);
160 const unsigned char *secret = (
const unsigned char *)
ipsumlorem;
161 size_t secret_len = strlen((
const char *)secret);
165 bool ret =
ssl_tls1_PRF(seed, (
int)seed_len, secret, (
int)secret_len, out,
sizeof(out));
167#if defined(LIBRESSL_VERSION_NUMBER) || defined(ENABLE_CRYPTO_WOLFSSL)
172 uint8_t good_prf[32] = {0xd9, 0x8c, 0x85, 0x18, 0xc8, 0x5e, 0x94, 0x69,
173 0x27, 0x91, 0x6a, 0xcf, 0xc2, 0xd5, 0x92, 0xfb,
174 0xb1, 0x56, 0x7e, 0x4b, 0x4b, 0x14, 0x59, 0xe6,
175 0xa9, 0x04, 0xac, 0x2d, 0xda, 0xb7, 0x2d, 0x67};
176 assert_memory_equal(good_prf, out,
sizeof(out));
181static uint8_t
goodhash[20] = {0x58, 0xea, 0x5a, 0xf0, 0x42, 0x94, 0xe9, 0x17,
182 0xed, 0x84, 0xb9, 0xf0, 0x83, 0x30, 0x23, 0xae,
183 0x8b, 0xa7, 0x7e, 0xb8};
214 memset(
key, 0x55,
sizeof(
key));
233 struct frame f = { 0 };
245 assert_int_equal(linkmtu, 1400);
254 assert_int_equal(linkmtu, 1408);
260 assert_int_equal(linkmtu, 1440);
266 assert_int_equal(linkmtu, 1440);
272 assert_int_equal(linkmtu, 1444);
277 assert_int_equal(linkmtu, 1446);
286 assert_int_equal(linkmtu, 1445);
288#if defined(ENABLE_FRAGMENT)
292 assert_int_equal(linkmtu, 1449);
310 assert_int_equal(linkmtu, 1457);
316 assert_int_equal(linkmtu, 1457);
323 assert_int_equal(linkmtu, 1405);
329 assert_int_equal(linkmtu, 1449);
332#if defined(USE_COMP) && defined(ENABLE_FRAGMENT)
338 assert_int_equal(linkmtu, 1454);
343 assert_int_equal(linkmtu, 1464);
354 struct frame f = { 0 };
370 assert_int_equal(f.mss_fix, 952);
380 assert_int_equal(f.mss_fix, 952);
387 for (
int i = 990; i <= 1010; i++)
396 assert_int_equal(f.mss_fix, 911);
400 assert_int_equal(f.mss_fix, 943);
404 assert_int_equal(f.mss_fix, 927);
413 for (
int i = 990; i <= 1010; i++)
422 assert_int_equal(f.mss_fix, 910);
426 assert_int_equal(f.mss_fix, 942);
430 assert_int_equal(f.mss_fix, 926);
444 for (
int i = 900; i <= 1200; i++)
452 assert_int_equal(f.mss_fix, i - 4 - 4 - 16 - 40);
467 assert_int_equal(aeslimit, (1ull << 36) - 1);
474 assert_int_equal(aeslimit / L, 680390858);
478 assert_int_equal(aeslimit / L, 122059461);
486 {0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
487 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
488 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
489 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
491 uint8_t info[10] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
492 0xf6, 0xf7, 0xf8, 0xf9};
495 {0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
496 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
497 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
498 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
499 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
505 assert_memory_equal(out, okm,
sizeof(out));
513 {0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a,
514 0x06, 0x10, 0x4c, 0x9c, 0xeb, 0x35, 0xb4, 0x5c,
515 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01,
516 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44};
519 {0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
520 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
521 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
522 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
523 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
524 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
525 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
526 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
527 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
528 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
532 {0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
533 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
534 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
535 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
536 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
537 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
538 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
539 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
540 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
541 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
544 uint8_t out[82] = {0xaa};
547 assert_memory_equal(out, okm, L);
555 {0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16,
556 0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
557 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
558 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04};
564 {0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
565 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
566 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
567 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
568 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
574 assert_memory_equal(out, okm, L);
584 {0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
585 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
586 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
587 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
590 {0x00, 0x1b, 0x0e, 0x6f, 0x76, 0x70, 0x6e, 0x20,
591 0x75, 0x6e, 0x69, 0x74, 0x20, 0x74, 0x65, 0x73,
596 {0x87, 0x5a, 0x8e, 0xec, 0x18, 0x55, 0x63, 0x80,
597 0xb8, 0xd9, 0x33, 0xed, 0x32, 0x3c, 0x2d, 0xf8,
598 0xe8, 0xec, 0xcf, 0x49, 0x72, 0xe6, 0x83, 0xf0,
604 assert_memory_equal(out, okm, L);
611 {0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
612 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
613 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
614 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
616 const uint8_t *label = (
const uint8_t *) (
"unit test");
620 uint8_t out_expected[16] =
621 {0x18, 0x5e, 0xaa, 0x1c, 0x7f, 0x22, 0x8a, 0xb8,
622 0xeb, 0x29, 0x77, 0x32, 0x14, 0xd9, 0x20, 0x46};
624 assert_memory_equal(out, out_expected, 16);
627#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
634ossl_expand_label(
const uint8_t *secret,
size_t secret_len,
635 const uint8_t *label,
size_t label_len,
636 const uint8_t *
context,
size_t context_len,
637 uint8_t *out, uint16_t out_len)
640 const char *properties = NULL;
642 const uint8_t *label_prefix = (
const uint8_t *) (
"ovpn ");
643 const size_t label_prefix_len = 5;
645 EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_TLS1_3_KDF, properties);
646 assert_non_null(kdf);
648 const char *mdname =
"SHA-256";
652 EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
653 assert_non_null(kctx);
655 OSSL_PARAM params[7];
656 OSSL_PARAM *p = params;
658 int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
660 *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
661 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
663 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
664 (
unsigned char *) secret, hashlen);
665 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
666 (
unsigned char *) label_prefix,
668 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
669 (
unsigned char *) label, label_len);
671 *p++ = OSSL_PARAM_construct_end();
673 int ret = EVP_KDF_derive(kctx, out, out_len, params);
674 EVP_KDF_CTX_free(kctx);
677 assert_int_equal(ret, 1);
685 {0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
686 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
687 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
688 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
690 const uint8_t *label = (
const uint8_t *) (
"unit test");
691 const size_t labellen = 9;
694 ossl_expand_label(secret,
sizeof(secret), label, labellen, NULL, 0, out,
sizeof(out));
697 uint8_t out_ovpn[27];
699 ovpn_expand_label(secret,
sizeof(secret), label, 9, NULL, 0, out_ovpn,
sizeof(out_ovpn));
700 assert_memory_equal(out_ovpn, out,
sizeof(out_ovpn));
721 int *num_future_keys = (
int *)*state;
729 struct epoch_key epoch1send = { .
epoch = 1, .epoch_key = {0x23} };
730 struct epoch_key epoch1recv = { .
epoch = 1, .epoch_key = {0x27} };
733 &epoch1recv, *num_future_keys);
789 for (
int i = 0; i < 4; i++)
928 uint8_t exp_cipherkey[24] =
929 {0xed, 0x85, 0x33, 0xdb, 0x1c, 0x28, 0xac, 0xe4,
930 0x18, 0xe9, 0x00, 0x6a, 0xb2, 0x9c, 0x17, 0x41,
931 0x7d, 0x60, 0xeb, 0xe6, 0xcd, 0x90, 0xbf, 0x0a};
933 uint8_t exp_impl_iv[12] =
934 {0x86, 0x89, 0x0a, 0xab, 0xf0, 0x32, 0xcb, 0x59, 0xf4, 0xcf, 0xa3, 0x4e};
943 int prestate_num13 = 13;
944 int prestate_num16 = 16;
945 int prestate_num32 = 32;
948 const struct CMUnitTest tests[] = {
981#if defined(ENABLE_CRYPTO_OPENSSL)
982 OpenSSL_add_all_algorithms();
985 int ret = cmocka_run_group_tests_name(
"crypto tests", tests, NULL, NULL);
987#if defined(ENABLE_CRYPTO_OPENSSL)
char * string_alloc(const char *str, struct gc_arena *gc)
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
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_type(struct key_type *kt, const char *ciphername, const char *authname, bool tls_mode, bool warn)
Initialize a key_type structure with.
uint64_t cipher_get_aead_limits(const char *ciphername)
Check if the cipher is an AEAD cipher and needs to be limited to a certain number of number of blocks...
void free_key_ctx(struct key_ctx *ctx)
Data Channel Cryptography Module.
void hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
hmac_ctx_t * hmac_ctx_new(void)
void hmac_ctx_reset(hmac_ctx_t *ctx)
void hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, const char *mdname)
void hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
bool ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret, int secret_len, uint8_t *output, int output_len)
Calculates the TLS 1.0-1.1 PRF function.
bool crypto_pem_decode(const char *name, struct buffer *dst, const struct buffer *src)
Decode a PEM buffer to binary data.
static bool cipher_valid(const char *ciphername)
Returns if the cipher is valid, based on the given cipher name.
void hmac_ctx_free(hmac_ctx_t *ctx)
const char * cipher_kt_name(const char *ciphername)
Retrieve a normalised string describing the cipher (e.g.
void hmac_ctx_cleanup(hmac_ctx_t *ctx)
unsigned char md_kt_size(const char *mdname)
Returns the size of the message digest, in bytes.
bool crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src, struct gc_arena *gc)
Encode binary data as PEM.
bool ovpn_expand_label(const uint8_t *secret, size_t secret_len, const uint8_t *label, size_t label_len, const uint8_t *context, size_t context_len, uint8_t *out, uint16_t out_len)
Variant of the RFC 8446 TLS 1.3 HKDF-Expand-Label function with the following differences/restriction...
void epoch_generate_future_receive_keys(struct crypto_options *co)
Generates and fills the epoch_data_keys_future with next valid future keys in crypto_options using th...
void epoch_replace_update_recv_key(struct crypto_options *co, uint16_t new_epoch)
This is called when the peer uses a new send key that is not the default key.
void free_epoch_key_ctx(struct crypto_options *co)
Frees the extra data structures used by epoch keys in crypto_options.
struct key_ctx * epoch_lookup_decrypt_key(struct crypto_options *opt, uint16_t epoch)
Using an epoch, this function will try to retrieve a decryption key context that matches that epoch f...
void epoch_init_key_ctx(struct crypto_options *co, const struct key_type *key_type, const struct epoch_key *e1_send, const struct epoch_key *e1_recv, uint16_t future_key_count)
Initialises data channel keys and internal structures for epoch data keys using the provided E0 epoch...
void epoch_data_key_derive(struct key_parameters *key, const struct epoch_key *epoch_key, const struct key_type *kt)
Generate a data channel key pair from the epoch key.
void ovpn_hkdf_expand(const uint8_t *secret, const uint8_t *info, int info_len, uint8_t *out, int out_len)
Implementation of the RFC5869 HKDF-Expand function with the following restrictions.
void epoch_iterate_send_key(struct crypto_options *co)
Updates the send key and send_epoch_key in cryptio_options->key_ctx_bi to use the next epoch.
mbedtls_md_context_t hmac_ctx_t
Generic HMAC context.
#define SHA256_DIGEST_LENGTH
void frame_calculate_dynamic(struct frame *frame, struct key_type *kt, const struct options *options, struct link_socket_info *lsi)
Set the –mssfix option.
size_t calc_options_string_link_mtu(const struct options *o, const struct frame *frame)
Calculate the link-mtu to advertise to our peer.
Control Channel SSL library backend module.
Wrapper structure for dynamically allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
const char * socks_proxy_server
Contains all state information for one tunnel.
Security parameter state for processing data channel packets.
struct epoch_key epoch_key_send
last epoch_key used for generation of the current send data keys.
struct key_ctx epoch_retiring_data_receive_key
The old key before the sender switched to a new epoch data key.
struct key_ctx * epoch_data_keys_future
Keeps the future epoch data keys for decryption.
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
uint16_t epoch_data_keys_future_count
number of keys stored in epoch_data_keys_future
struct epoch_key epoch_key_recv
epoch_key used for the highest receive epoch keys
Packet geometry parameters.
Garbage collection arena used to keep track of dynamically allocated memory.
struct key_ctx decrypt
cipher and/or HMAC contexts for receiving direction.
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
uint16_t epoch
OpenVPN data channel epoch, this variable holds the epoch number this key belongs to.
internal structure similar to struct key that holds key information but is not represented on wire an...
int hmac_size
Number of bytes set in the HMac key material.
int cipher_size
Number of bytes set in the cipher key material.
uint8_t hmac[MAX_HMAC_KEY_LENGTH]
Key material for HMAC operations.
uint8_t cipher[MAX_CIPHER_KEY_LENGTH]
Key material for cipher operations.
Container for unidirectional cipher and HMAC key material.
struct compress_options comp
const char * tls_auth_file
struct connection_entry ce
const char * shared_secret_file
static void openvpn_unit_test_setup(void)
Sets up the environment for unit tests like making both stderr and stdout non-buffered to avoid messa...
void crypto_test_ovpn_label_expand(void **state)
void crypto_test_hkdf_expand_testa2(void **state)
static void test_mssfix_mtu_calculation(void **state)
void crypto_test_hkdf_expand_testa1(void **state)
static uint8_t testkey[20]
static void test_cipher_names(const char *ciphername, const char *openvpn_name)
void crypto_test_hkdf_expand_testa3(void **state)
void crypto_test_ovpn_expand_openssl3(void **state)
static void test_translate_cipher(const char *ciphername, const char *openvpn_name)
static void crypto_translate_cipher_names(void **state)
void crypto_test_epoch_key_receive_lookup(void **state)
void crypto_test_epoch_key_rotation(void **state)
static uint8_t goodhash[20]
static const char testtext[]
static int crypto_test_epoch_teardown(void **state)
static void crypto_test_hmac(void **state)
void crypto_test_aead_limits(void **state)
static void crypto_pem_encode_decode_loopback(void **state)
void crypto_test_epoch_key_generation(void **state)
static const char * ipsumlorem
static int crypto_test_epoch_setup(void **state)
void epoch_test_derive_data_key(void **state)
void crypto_test_epoch_key_overflow(void **state)
static void crypto_test_tls_prf(void **state)
static void test_occ_mtu_calculation(void **state)
void crypto_test_hkdf_expand_test_ovpn(void **state)