OpenVPN
test_crypto.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2016-2026 Sentyron B.V. <openvpn@sentyron.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <stdarg.h>
32#include <string.h>
33#include <setjmp.h>
34#include <inttypes.h>
35#include <cmocka.h>
36
37#include "crypto.h"
38#include "crypto_epoch.h"
39#include "options.h"
40#include "ssl_backend.h"
41#include "siphash.h"
42#include "siphash_openssl.h"
43
44#include "mss.h"
45#include "test_common.h"
46
47
48#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
49#include <openssl/core_names.h>
50#include <openssl/kdf.h>
51#endif
52
53static const char testtext[] = "Dummy text to test PEM encoding";
54
55static void
57{
58 struct gc_arena gc = gc_new();
59 struct buffer src_buf;
60 buf_set_read(&src_buf, (void *)testtext, sizeof(testtext));
61
62 uint8_t dec[sizeof(testtext)];
63 struct buffer dec_buf;
64 buf_set_write(&dec_buf, dec, sizeof(dec));
65
66 struct buffer pem_buf;
67
68 assert_true(crypto_pem_encode("TESTKEYNAME", &pem_buf, &src_buf, &gc));
70
71 /* Wrong key name */
73
74 assert_true(crypto_pem_decode("TESTKEYNAME", &dec_buf, &pem_buf));
77
78 gc_free(&gc);
79}
80
81static void
82test_translate_cipher(const char *ciphername, const char *openvpn_name)
83{
84 bool cipher = cipher_valid(ciphername);
85
86 /* Empty cipher is fine */
87 if (!cipher)
88 {
89 return;
90 }
91
92 const char *kt_name = cipher_kt_name(ciphername);
93
94 assert_string_equal(kt_name, openvpn_name);
95}
96
97static void
98test_cipher_names(const char *ciphername, const char *openvpn_name)
99{
100 struct gc_arena gc = gc_new();
101 /* Go through some variants, if the cipher library accepts these, they
102 * should be normalised to the openvpn name */
103 char *upper = string_alloc(ciphername, &gc);
104 char *lower = string_alloc(ciphername, &gc);
105 char *random_case = string_alloc(ciphername, &gc);
106
107 for (size_t i = 0; i < strlen(ciphername); i++)
108 {
109 upper[i] = (char)toupper((unsigned char)ciphername[i]);
110 lower[i] = (char)tolower((unsigned char)ciphername[i]);
111 if (rand() & 0x1)
112 {
113 random_case[i] = upper[i];
114 }
115 else
116 {
117 random_case[i] = lower[i];
118 }
119 }
120
121 if (!openvpn_name)
122 {
123 openvpn_name = upper;
124 }
125
126 test_translate_cipher(upper, openvpn_name);
127 test_translate_cipher(lower, openvpn_name);
128 test_translate_cipher(random_case, openvpn_name);
129 test_translate_cipher(ciphername, openvpn_name);
130
131
132 gc_free(&gc);
133}
134
135static void
137{
138 /* Test that a number of ciphers to see that they turn out correctly */
139 test_cipher_names("BF-CBC", NULL);
140 test_cipher_names("BLOWFISH-CBC", "BF-CBC");
141 test_cipher_names("Chacha20-Poly1305", NULL);
142 test_cipher_names("AES-128-GCM", NULL);
143 test_cipher_names("AES-128-CBC", NULL);
144 test_cipher_names("CAMELLIA-128-CFB128", "CAMELLIA-128-CFB");
145 test_cipher_names("id-aes256-GCM", "AES-256-GCM");
146}
147
148
149static const char *ipsumlorem = "Lorem ipsum dolor sit amet, consectetur "
150 "adipisici elit, sed eiusmod tempor incidunt "
151 "ut labore et dolore magna aliqua.";
152
153static void
155{
156 const char *seedstr = "Quis aute iure reprehenderit in voluptate "
157 "velit esse cillum dolore";
158 const unsigned char *seed = (const unsigned char *)seedstr;
159 const size_t seed_len = strlen(seedstr);
160
161
162 const unsigned char *secret = (const unsigned char *)ipsumlorem;
163 size_t secret_len = strlen((const char *)secret);
164
165
166 uint8_t out[32];
167 bool ret = ssl_tls1_PRF(seed, seed_len, secret, secret_len, out, sizeof(out));
168
169#if defined(LIBRESSL_VERSION_NUMBER) || defined(ENABLE_CRYPTO_WOLFSSL)
170 /* No TLS1 PRF support in these libraries */
171 assert_false(ret);
172#else
173 assert_true(ret);
174 uint8_t good_prf[32] = { 0xd9, 0x8c, 0x85, 0x18, 0xc8, 0x5e, 0x94, 0x69, 0x27, 0x91, 0x6a,
175 0xcf, 0xc2, 0xd5, 0x92, 0xfb, 0xb1, 0x56, 0x7e, 0x4b, 0x4b, 0x14,
176 0x59, 0xe6, 0xa9, 0x04, 0xac, 0x2d, 0xda, 0xb7, 0x2d, 0x67 };
177 assert_memory_equal(good_prf, out, sizeof(out));
178#endif
179}
180
181static uint8_t testkey[20] = { 0x0b, 0x00 };
182static uint8_t goodhash[20] = { 0x58, 0xea, 0x5a, 0xf0, 0x42, 0x94, 0xe9, 0x17, 0xed, 0x84,
183 0xb9, 0xf0, 0x83, 0x30, 0x23, 0xae, 0x8b, 0xa7, 0x7e, 0xb8 };
184
185static void
186crypto_test_hmac(void **state)
187{
188 hmac_ctx_t *hmac = hmac_ctx_new();
189
190 assert_int_equal(md_kt_size("SHA1"), 20);
191
192 uint8_t key[20];
193 memcpy(key, testkey, sizeof(key));
194
195 hmac_ctx_init(hmac, key, "SHA1");
196 hmac_ctx_update(hmac, (const uint8_t *)ipsumlorem, (int)strlen(ipsumlorem));
197 hmac_ctx_update(hmac, (const uint8_t *)ipsumlorem, (int)strlen(ipsumlorem));
198
199 uint8_t hash[20];
200 hmac_ctx_final(hmac, hash);
201
202 assert_memory_equal(hash, goodhash, sizeof(hash));
203 memset(hash, 0x00, sizeof(hash));
204
205 /* try again */
206 hmac_ctx_reset(hmac);
207 hmac_ctx_update(hmac, (const uint8_t *)ipsumlorem, (int)strlen(ipsumlorem));
208 hmac_ctx_update(hmac, (const uint8_t *)ipsumlorem, (int)strlen(ipsumlorem));
209 hmac_ctx_final(hmac, hash);
210
211 assert_memory_equal(hash, goodhash, sizeof(hash));
212
213 /* Fill our key with random data to ensure it is not used by hmac anymore */
214 memset(key, 0x55, sizeof(key));
215
216 hmac_ctx_reset(hmac);
217 hmac_ctx_update(hmac, (const uint8_t *)ipsumlorem, (int)strlen(ipsumlorem));
218 hmac_ctx_update(hmac, (const uint8_t *)ipsumlorem, (int)strlen(ipsumlorem));
219 hmac_ctx_final(hmac, hash);
220
221 assert_memory_equal(hash, goodhash, sizeof(hash));
222 hmac_ctx_cleanup(hmac);
223 hmac_ctx_free(hmac);
224}
225
226/* This test is in test_crypto as it calls into the functions that calculate
227 * the crypto overhead */
228static void
230{
231 struct gc_arena gc = gc_new();
232
233 struct frame f = { 0 };
234 struct options o = { 0 };
235 size_t linkmtu;
236
237 /* common defaults */
238 o.ce.tun_mtu = 1400;
239 o.ce.proto = PROTO_UDP;
240
241 /* No crypto at all */
242 o.ciphername = "none";
243 o.authname = "none";
244 linkmtu = calc_options_string_link_mtu(&o, &f);
245 assert_int_equal(linkmtu, 1400);
246
247 /* Static key OCC examples */
248 o.shared_secret_file = "not null";
249
250 /* secret, auth none, cipher none */
251 o.ciphername = "none";
252 o.authname = "none";
253 linkmtu = calc_options_string_link_mtu(&o, &f);
254 assert_int_equal(linkmtu, 1408);
255
256 /* secret, cipher AES-128-CBC, auth none */
257 o.ciphername = "AES-128-CBC";
258 o.authname = "none";
259 linkmtu = calc_options_string_link_mtu(&o, &f);
260 assert_int_equal(linkmtu, 1440);
261
262 /* secret, cipher none, auth SHA256 */
263 o.ciphername = "none";
264 o.authname = "SHA256";
265 linkmtu = calc_options_string_link_mtu(&o, &f);
266 assert_int_equal(linkmtu, 1440);
267
268 /* secret, cipher BF-CBC, auth SHA1 */
269 o.ciphername = "BF-CBC";
270 o.authname = "SHA1";
271 linkmtu = calc_options_string_link_mtu(&o, &f);
272 assert_int_equal(linkmtu, 1444);
273
274 /* secret, cipher BF-CBC, auth SHA1, tcp-client */
276 linkmtu = calc_options_string_link_mtu(&o, &f);
277 assert_int_equal(linkmtu, 1446);
278
279 o.ce.proto = PROTO_UDP;
280
281#if defined(USE_COMP)
283
284 /* secret, comp-lzo yes, cipher BF-CBC, auth SHA1 */
285 linkmtu = calc_options_string_link_mtu(&o, &f);
286 assert_int_equal(linkmtu, 1445);
287
288#if defined(ENABLE_FRAGMENT)
289 /* secret, comp-lzo yes, cipher BF-CBC, auth SHA1, fragment 1200 */
290 o.ce.fragment = 1200;
291 linkmtu = calc_options_string_link_mtu(&o, &f);
292 assert_int_equal(linkmtu, 1449);
293 o.ce.fragment = 0;
294#endif
295
297#endif
298
299 /* TLS mode */
300 o.shared_secret_file = NULL;
301 o.tls_client = true;
302 o.pull = true;
303
304 /* tls client, cipher AES-128-CBC, auth SHA1, tls-auth */
305 o.authname = "SHA1";
306 o.ciphername = "AES-128-CBC";
307 o.tls_auth_file = "dummy";
308
309 linkmtu = calc_options_string_link_mtu(&o, &f);
310 assert_int_equal(linkmtu, 1457);
311
312 /* tls client, cipher AES-128-CBC, auth SHA1 */
313 o.tls_auth_file = NULL;
314
315 linkmtu = calc_options_string_link_mtu(&o, &f);
316 assert_int_equal(linkmtu, 1457);
317
318 /* tls client, cipher none, auth none */
319 o.authname = "none";
320 o.ciphername = "none";
321
322 linkmtu = calc_options_string_link_mtu(&o, &f);
323 assert_int_equal(linkmtu, 1405);
324
325 /* tls client, auth SHA1, cipher AES-256-GCM */
326 o.authname = "SHA1";
327 o.ciphername = "AES-256-GCM";
328 linkmtu = calc_options_string_link_mtu(&o, &f);
329 assert_int_equal(linkmtu, 1449);
330
331
332#if defined(USE_COMP) && defined(ENABLE_FRAGMENT)
334
335 /* tls client, auth SHA1, cipher AES-256-GCM, fragment, comp-lzo yes */
336 o.ce.fragment = 1200;
337 linkmtu = calc_options_string_link_mtu(&o, &f);
338 assert_int_equal(linkmtu, 1454);
339
340 /* tls client, auth SHA1, cipher AES-256-GCM, fragment, comp-lzo yes, socks */
341 o.ce.socks_proxy_server = "socks.example.com";
342 linkmtu = calc_options_string_link_mtu(&o, &f);
343 assert_int_equal(linkmtu, 1464);
344#endif
345
346 gc_free(&gc);
347}
348
349static void
351{
352 struct gc_arena gc = gc_new();
353
354 struct frame f = { 0 };
355 struct options o = { 0 };
356
357 /* common defaults */
358 o.ce.tun_mtu = 1400;
359 o.ce.mssfix = 1000;
360 o.ce.proto = PROTO_UDP;
361
362 /* No crypto at all */
363 o.ciphername = "none";
364 o.authname = "none";
365 struct key_type kt;
366 init_key_type(&kt, o.ciphername, o.authname, false, false);
367
368 /* No encryption, just packet id (8) + TCP payload(20) + IP payload(20) */
369 frame_calculate_dynamic(&f, &kt, &o, NULL);
370 assert_int_equal(f.mss_fix, 952);
371
372 /* Static key OCC examples */
373 o.shared_secret_file = "not null";
374
375 /* secret, auth none, cipher none */
376 o.ciphername = "none";
377 o.authname = "none";
378 init_key_type(&kt, o.ciphername, o.authname, false, false);
379 frame_calculate_dynamic(&f, &kt, &o, NULL);
380 assert_int_equal(f.mss_fix, 952);
381
382 /* secret, cipher AES-128-CBC, auth none */
383 o.ciphername = "AES-128-CBC";
384 o.authname = "none";
385 init_key_type(&kt, o.ciphername, o.authname, false, false);
386
387 for (int i = 990; i <= 1010; i++)
388 {
389 /* 992 - 1008 should end up with the same mssfix value all they
390 * all result in the same CBC block size/padding and <= 991 and >=1008
391 * should be one block less and more respectively */
392 o.ce.mssfix = i;
393 frame_calculate_dynamic(&f, &kt, &o, NULL);
394 if (i <= 991)
395 {
396 assert_int_equal(f.mss_fix, 911);
397 }
398 else if (i >= 1008)
399 {
400 assert_int_equal(f.mss_fix, 943);
401 }
402 else
403 {
404 assert_int_equal(f.mss_fix, 927);
405 }
406 }
407#ifdef USE_COMP
409
410 /* Same but with compression added. Compression adds one byte extra to the
411 * payload so the payload should be reduced by compared to the no
412 * compression calculation before */
413 for (int i = 990; i <= 1010; i++)
414 {
415 /* 992 - 1008 should end up with the same mssfix value all they
416 * all result in the same CBC block size/padding and <= 991 and >=1008
417 * should be one block less and more respectively */
418 o.ce.mssfix = i;
419 frame_calculate_dynamic(&f, &kt, &o, NULL);
420 if (i <= 991)
421 {
422 assert_int_equal(f.mss_fix, 910);
423 }
424 else if (i >= 1008)
425 {
426 assert_int_equal(f.mss_fix, 942);
427 }
428 else
429 {
430 assert_int_equal(f.mss_fix, 926);
431 }
432 }
434#endif /* ifdef USE_COMP */
435
436 /* tls client, auth SHA1, cipher AES-256-GCM */
437 o.authname = "SHA1";
438 o.ciphername = "AES-256-GCM";
439 o.tls_client = true;
440 o.peer_id = 77;
441 o.use_peer_id = true;
442 init_key_type(&kt, o.ciphername, o.authname, true, false);
443
444 for (int i = 900; i <= 1200; i++)
445 {
446 /* For stream ciphers, the value should not be influenced by block
447 * sizes or similar but always have the same difference */
448 o.ce.mssfix = i;
449 frame_calculate_dynamic(&f, &kt, &o, NULL);
450
451 /* 4 byte opcode/peerid, 4 byte pkt ID, 16 byte tag, 40 TCP+IP */
452 assert_int_equal(f.mss_fix, i - 4 - 4 - 16 - 40);
453 }
454
455 gc_free(&gc);
456}
457
458void
460{
461 /* if ChaCha20-Poly1305 is not supported by the crypto library or in the
462 * current mode (FIPS), this will still return -1 */
463 assert_int_equal(cipher_get_aead_limits("CHACHA20-POLY1305"), 0);
464
465 int64_t aeslimit = cipher_get_aead_limits("AES-128-GCM");
466
467 assert_int_equal(aeslimit, (1ull << 36) - 1);
468
469 /* Check if this matches our exception for 1600 size packets assuming
470 * AEAD_LIMIT_BLOCKSIZE (128 bits/ 16 bytes). Gives us 100 blocks
471 * + 1 for the packet */
472 int64_t L = 101;
473 /* 2 ^ 29.34, using the result here to avoid linking to libm */
474 assert_int_equal(aeslimit / L, 680390858);
475
476 /* and for 9000, 2^26.86 */
477 L = 563;
478 assert_int_equal(aeslimit / L, 122059461);
479}
480
481void
483{
484 /* RFC 5889 A.1 Test Case 1 */
485 const uint8_t prk[32] = { 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f,
486 0x0d, 0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f,
487 0x9c, 0x31, 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5 };
488
489 uint8_t info[10] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 };
490
491 uint8_t okm[42] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f,
492 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a,
493 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34,
494 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65 };
495
496 uint8_t out[42];
497 ovpn_hkdf_expand(prk, info, sizeof(info), out, sizeof(out));
498
499 assert_memory_equal(out, okm, sizeof(out));
500}
501
502void
504{
505 /* RFC 5889 A.2 Test Case 2 */
506 const uint8_t prk[32] = { 0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a, 0x06, 0x10, 0x4c,
507 0x9c, 0xeb, 0x35, 0xb4, 0x5c, 0xef, 0x76, 0x00, 0x14, 0x90, 0x46,
508 0x71, 0x01, 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44 };
509
510 uint8_t info[80] = { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
511 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
512 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
513 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
514 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
515 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
516 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
517
518 const int L = 82;
519 uint8_t okm[82] = { 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c,
520 0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
521 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99,
522 0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
523 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9,
524 0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
525 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87 };
526
527 uint8_t out[82] = { 0xaa };
528 ovpn_hkdf_expand(prk, info, sizeof(info), out, L);
529
530 assert_memory_equal(out, okm, L);
531}
532
533void
535{
536 /* RFC 5889 A.3 Test Case 3 */
537 const uint8_t prk[32] = { 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16, 0x7f, 0x33, 0xa9,
538 0x1d, 0x6f, 0x64, 0x8b, 0xdf, 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb,
539 0x63, 0x77, 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04 };
540
541 const uint8_t info[] = { 0 };
542
543 int L = 42;
544 uint8_t okm[42] = { 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80,
545 0x2a, 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1,
546 0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d,
547 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8 };
548
549 uint8_t out[42];
550 ovpn_hkdf_expand(prk, info, 0, out, L);
551
552 assert_memory_equal(out, okm, L);
553}
554
555void
557{
558 /* tests the HDKF with a label/okm that OpenVPN itself uses in OpenSSL 3
559 * HDKF unit test*/
560
561 const uint8_t prk[32] = { 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f,
562 0x0d, 0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f,
563 0x9c, 0x31, 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5 };
564
565 uint8_t info[18] = { 0x00, 0x1b, 0x0e, 0x6f, 0x76, 0x70, 0x6e, 0x20, 0x75,
566 0x6e, 0x69, 0x74, 0x20, 0x74, 0x65, 0x73, 0x74, 0x00 };
567
568 int L = 27;
569 uint8_t okm[27] = { 0x87, 0x5a, 0x8e, 0xec, 0x18, 0x55, 0x63, 0x80, 0xb8,
570 0xd9, 0x33, 0xed, 0x32, 0x3c, 0x2d, 0xf8, 0xe8, 0xec,
571 0xcf, 0x49, 0x72, 0xe6, 0x83, 0xf0, 0x6a, 0x83, 0xac };
572
573 uint8_t out[27];
574 ovpn_hkdf_expand(prk, info, sizeof(info), out, L);
575
576 assert_memory_equal(out, okm, L);
577}
578
579void
581{
582 uint8_t secret[32] = { 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f,
583 0x0d, 0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f,
584 0x9c, 0x31, 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5 };
585
586 const uint8_t *label = (const uint8_t *)("unit test");
587 uint8_t out[16];
588 ovpn_expand_label(secret, sizeof(secret), label, 9, NULL, 0, out, sizeof(out));
589
590 uint8_t out_expected[16] = { 0x18, 0x5e, 0xaa, 0x1c, 0x7f, 0x22, 0x8a, 0xb8,
591 0xeb, 0x29, 0x77, 0x32, 0x14, 0xd9, 0x20, 0x46 };
592
593 assert_memory_equal(out, out_expected, 16);
594}
595
596#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
597/* We have OpenSSL 3.0+, we test if their implementation matches our
598 * implementation. We currently do not use this code from the crypto library
599 * in the main code yet as we don't want to repeat the mess that the current
600 * openvpn_PRF ifdef maze */
601
602bool
603ossl_expand_label(const uint8_t *secret, size_t secret_len, const uint8_t *label, size_t label_len,
604 const uint8_t *context, size_t context_len, uint8_t *out, uint16_t out_len)
605{
606 OSSL_LIB_CTX *libctx = NULL;
607 const char *properties = NULL;
608
609 const uint8_t *label_prefix = (const uint8_t *)("ovpn ");
610 const size_t label_prefix_len = 5;
611
612 EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_TLS1_3_KDF, properties);
613 assert_non_null(kdf);
614
615 const char *mdname = "SHA-256";
616
617 size_t hashlen = SHA256_DIGEST_LENGTH;
618
619 EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
620 assert_non_null(kctx);
621
622 OSSL_PARAM params[7];
623 OSSL_PARAM *p = params;
624
625 int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
626
627 *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
628 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0);
629 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (unsigned char *)secret, hashlen);
630 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX, (unsigned char *)label_prefix,
631 label_prefix_len);
632 *p++ =
633 OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL, (unsigned char *)label, label_len);
634
635 *p++ = OSSL_PARAM_construct_end();
636
637 int ret = EVP_KDF_derive(kctx, out, out_len, params);
638 EVP_KDF_CTX_free(kctx);
639 EVP_KDF_free(kdf);
640
641 assert_int_equal(ret, 1);
642 return true;
643}
644
645void
647{
648 uint8_t secret[32] = { 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f,
649 0x0d, 0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f,
650 0x9c, 0x31, 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5 };
651
652 const uint8_t *label = (const uint8_t *)("unit test");
653 const size_t labellen = 9;
654 uint8_t out[27];
655
656 ossl_expand_label(secret, sizeof(secret), label, labellen, NULL, 0, out, sizeof(out));
657
658 /* Do the same derivation with our own function */
659 uint8_t out_ovpn[27];
660
661 ovpn_expand_label(secret, sizeof(secret), label, 9, NULL, 0, out_ovpn, sizeof(out_ovpn));
662 assert_memory_equal(out_ovpn, out, sizeof(out_ovpn));
663}
664
665#else /* if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L */
666void
668{
669 skip();
670}
671#endif /* if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L */
672
674{
675 struct key_type kt;
676 struct gc_arena gc;
678};
679
680static int
682{
683 const uint16_t *num_future_keys = (uint16_t *)*state;
684 struct epoch_test_state *data = calloc(1, sizeof(struct epoch_test_state));
685
686 data->gc = gc_new();
687
688 init_key_type(&data->kt, "AES-128-GCM", "none", true, false);
689
690 /* have an epoch key that uses 0x23 for the key for all bytes */
691 struct epoch_key epoch1send = { .epoch = 1, .epoch_key = { 0x23 } };
692 struct epoch_key epoch1recv = { .epoch = 1, .epoch_key = { 0x27 } };
693
694 epoch_init_key_ctx(&data->co, &data->kt, &epoch1send, &epoch1recv, *num_future_keys);
695
696 *state = data;
697 return 0;
698}
699
700static int
702{
703 struct epoch_test_state *data = *state;
704 free_epoch_key_ctx(&data->co);
706 gc_free(&data->gc);
707 free(*state);
708 return 0;
709}
710
711void
713{
714 struct epoch_test_state *data = *state;
715 struct crypto_options *co = &data->co;
716
717 /* check the keys look like expect */
718 assert_int_equal(co->epoch_data_keys_future[0].epoch, 2);
719 assert_int_equal(co->epoch_data_keys_future[15].epoch, 17);
720 assert_int_equal(co->epoch_key_send.epoch, 1);
721 assert_int_equal(co->epoch_key_recv.epoch, 17);
722
723 /* Now replace the recv key with the 6th future key (epoch = 8) */
725 assert_int_equal(co->epoch_data_keys_future[6].epoch, 8);
728
730 assert_int_equal(co->epoch_data_keys_future[0].epoch, 9);
731 assert_int_equal(co->epoch_data_keys_future[15].epoch, 24);
732}
733
734
735void
737{
738 struct epoch_test_state *data = *state;
739 struct crypto_options *co = &data->co;
740
741 /* should replace send + key recv */
743
744 assert_int_equal(co->key_ctx_bi.decrypt.epoch, 9);
745 assert_int_equal(co->key_ctx_bi.encrypt.epoch, 9);
746 assert_int_equal(co->epoch_key_send.epoch, 9);
747 assert_int_equal(co->epoch_retiring_data_receive_key.epoch, 1);
748
749 /* Iterate the data send key four times to get it to 13 */
750 for (int i = 0; i < 4; i++)
751 {
753 }
754 assert_int_equal(co->key_ctx_bi.encrypt.epoch, 13);
755
757 assert_int_equal(co->key_ctx_bi.decrypt.epoch, 10);
758 assert_int_equal(co->key_ctx_bi.encrypt.epoch, 13);
759 assert_int_equal(co->epoch_key_send.epoch, 13);
760 assert_int_equal(co->epoch_retiring_data_receive_key.epoch, 9);
761
763 assert_int_equal(co->key_ctx_bi.decrypt.epoch, 12);
764 assert_int_equal(co->key_ctx_bi.encrypt.epoch, 13);
765 assert_int_equal(co->epoch_key_send.epoch, 13);
766 assert_int_equal(co->epoch_retiring_data_receive_key.epoch, 10);
767
769 assert_int_equal(co->key_ctx_bi.encrypt.epoch, 14);
770}
771
772void
774{
775 struct epoch_test_state *data = *state;
776 struct crypto_options *co = &data->co;
777
778 /* lookup some wacky things that should fail */
779 assert_null(epoch_lookup_decrypt_key(co, 2000));
780 assert_null(epoch_lookup_decrypt_key(co, -1));
781 assert_null(epoch_lookup_decrypt_key(co, 0xefff));
782
783 /* Lookup the edges of the current window */
784 assert_null(epoch_lookup_decrypt_key(co, 0));
785 assert_int_equal(co->epoch_retiring_data_receive_key.epoch, 0);
786 assert_int_equal(epoch_lookup_decrypt_key(co, 1)->epoch, 1);
787 assert_int_equal(epoch_lookup_decrypt_key(co, 2)->epoch, 2);
788 assert_int_equal(epoch_lookup_decrypt_key(co, 13)->epoch, 13);
789 assert_int_equal(epoch_lookup_decrypt_key(co, 14)->epoch, 14);
790 assert_null(epoch_lookup_decrypt_key(co, 15));
791
792 /* Should move 1 to retiring key but leave 2-6 undefined, 7 as
793 * active and 8-20 as future keys*/
795
796 assert_null(epoch_lookup_decrypt_key(co, 0));
797 assert_int_equal(epoch_lookup_decrypt_key(co, 1)->epoch, 1);
798 assert_ptr_equal(epoch_lookup_decrypt_key(co, 1), &co->epoch_retiring_data_receive_key);
799
800 assert_null(epoch_lookup_decrypt_key(co, 2));
801 assert_null(epoch_lookup_decrypt_key(co, 3));
802 assert_null(epoch_lookup_decrypt_key(co, 4));
803 assert_null(epoch_lookup_decrypt_key(co, 5));
804 assert_null(epoch_lookup_decrypt_key(co, 6));
805 assert_int_equal(epoch_lookup_decrypt_key(co, 7)->epoch, 7);
806 assert_int_equal(epoch_lookup_decrypt_key(co, 8)->epoch, 8);
807 assert_int_equal(epoch_lookup_decrypt_key(co, 20)->epoch, 20);
808 assert_null(epoch_lookup_decrypt_key(co, 21));
809 assert_null(epoch_lookup_decrypt_key(co, 22));
810
811
812 /* Should move 7 to retiring key and have 8 as active key and
813 * 9-21 as future keys */
815 assert_null(epoch_lookup_decrypt_key(co, 0));
816 assert_null(epoch_lookup_decrypt_key(co, 1));
817 assert_null(epoch_lookup_decrypt_key(co, 2));
818 assert_null(epoch_lookup_decrypt_key(co, 3));
819 assert_null(epoch_lookup_decrypt_key(co, 4));
820 assert_null(epoch_lookup_decrypt_key(co, 5));
821 assert_null(epoch_lookup_decrypt_key(co, 6));
822 assert_int_equal(epoch_lookup_decrypt_key(co, 7)->epoch, 7);
823 assert_ptr_equal(epoch_lookup_decrypt_key(co, 7), &co->epoch_retiring_data_receive_key);
824 assert_int_equal(epoch_lookup_decrypt_key(co, 8)->epoch, 8);
825 assert_int_equal(epoch_lookup_decrypt_key(co, 20)->epoch, 20);
826 assert_int_equal(epoch_lookup_decrypt_key(co, 21)->epoch, 21);
827 assert_null(epoch_lookup_decrypt_key(co, 22));
828 assert_null(epoch_lookup_decrypt_key(co, 23));
829}
830
831void
833{
834 struct epoch_test_state *data = *state;
835 struct crypto_options *co = &data->co;
836
837 /* Modify the receive epoch and keys to have a very high epoch to test
838 * the end of array. Iterating through all 65k keys takes a 2-3s, so we
839 * avoid this for the unit test */
840 co->key_ctx_bi.decrypt.epoch = 65500;
841 co->key_ctx_bi.encrypt.epoch = 65500;
842
843 co->epoch_key_send.epoch = 65500;
845
846 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
847 {
848 co->epoch_data_keys_future[i].epoch = 65501 + i;
849 }
850
851 /* Move the last few keys until we are close to the limit */
852 while (co->key_ctx_bi.decrypt.epoch < (UINT16_MAX - 40))
853 {
855 }
856
857 /* Looking up this key should still work as it will not break the limit
858 * when generating keys */
859 assert_int_equal(epoch_lookup_decrypt_key(co, UINT16_MAX - 34)->epoch, UINT16_MAX - 34);
860 assert_int_equal(epoch_lookup_decrypt_key(co, UINT16_MAX - 33)->epoch, UINT16_MAX - 33);
861
862 /* This key is no longer eligible for decrypting as the 32 future keys
863 * would be larger than uint16_t maximum */
864 assert_int_equal(co->epoch_data_keys_future_count, 32);
865 assert_null(epoch_lookup_decrypt_key(co, UINT16_MAX - co->epoch_data_keys_future_count));
866 assert_null(epoch_lookup_decrypt_key(co, UINT16_MAX));
867
868 /* Check that moving to the last possible epoch works */
869 epoch_replace_update_recv_key(co, UINT16_MAX - 33);
870 assert_int_equal(epoch_lookup_decrypt_key(co, UINT16_MAX - 33)->epoch, UINT16_MAX - 33);
871 assert_null(epoch_lookup_decrypt_key(co, UINT16_MAX - 32));
872 assert_null(epoch_lookup_decrypt_key(co, UINT16_MAX));
873}
874
875void
877{
878 struct epoch_test_state *data = *state;
879 struct crypto_options *co = &data->co;
880
881 for (uint16_t i = 1; i <= 13; i++)
882 {
883 uint16_t current_epoch = co->key_ctx_bi.decrypt.epoch;
884 uint16_t target_epoch = current_epoch + i;
885
886 struct key_ctx *decrypt_key = epoch_lookup_decrypt_key(co, target_epoch);
887 assert_non_null(decrypt_key);
888
889 assert_int_equal(decrypt_key->epoch, target_epoch);
890
891 epoch_replace_update_recv_key(co, target_epoch);
892
893 assert_int_equal(co->key_ctx_bi.decrypt.epoch, target_epoch);
894 }
895
896 /* Check that 14 is not valid anymnore */
897 uint16_t current_epoch = co->key_ctx_bi.decrypt.epoch;
898 uint16_t target_epoch = current_epoch + 14;
899
900 struct key_ctx *decrypt_key = epoch_lookup_decrypt_key(co, target_epoch);
901 assert_null(decrypt_key);
902}
903
904void
906{
907 struct epoch_key e17 = { .epoch = 17, .epoch_key = { 19, 12 } };
908 struct key_type kt = { 0 };
909 struct key_parameters key_parameters = { 0 };
910 init_key_type(&kt, "AES-192-GCM", "none", true, false);
911
912
914
915 assert_int_equal(key_parameters.cipher_size, 24);
916 assert_int_equal(key_parameters.hmac_size, 12);
917
918 uint8_t exp_cipherkey[24] = { 0xed, 0x85, 0x33, 0xdb, 0x1c, 0x28, 0xac, 0xe4,
919 0x18, 0xe9, 0x00, 0x6a, 0xb2, 0x9c, 0x17, 0x41,
920 0x7d, 0x60, 0xeb, 0xe6, 0xcd, 0x90, 0xbf, 0x0a };
921
922 uint8_t exp_impl_iv[12] = { 0x86, 0x89, 0x0a, 0xab, 0xf0, 0x32,
923 0xcb, 0x59, 0xf4, 0xcf, 0xa3, 0x4e };
924
925 assert_memory_equal(key_parameters.cipher, exp_cipherkey, sizeof(exp_cipherkey));
926 assert_memory_equal(key_parameters.hmac, exp_impl_iv, sizeof(exp_impl_iv));
927}
928
929/* Use a define here since some c compilers don't like array initialisation
930 * with an integer */
931#define UT_SIPHASH_HASH_SIZE 16
932
933static const char *ut_message = "Look behind you, a Three-Headed Monkey!";
934static const uint8_t ut_key[SIPHASH_KEY_SIZE] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
935const uint8_t expected_hash[UT_SIPHASH_HASH_SIZE] = { 0x3e, 0xea, 0x95, 0xb2, 0x6d, 0x5c, 0x4e, 0xfa,
936 0x20, 0x47, 0x65, 0x7e, 0xdd, 0xcd, 0x62, 0x51 };
937
938static void
939test_siphash(void **state)
940{
941 uint8_t out[UT_SIPHASH_HASH_SIZE] = { 0 };
943 assert_memory_equal(out, expected_hash, UT_SIPHASH_HASH_SIZE);
944}
945
946static void
948{
950
951 if (!siphash_openssl_available(sipctx))
952 {
954 skip();
955 }
956
957 uint8_t out[UT_SIPHASH_HASH_SIZE] = { 0 };
958
959 siphash_openssl(sipctx, ut_message, strlen(ut_message), ut_key, out,
961 assert_memory_equal(out, expected_hash, UT_SIPHASH_HASH_SIZE);
962
963 /* check that calling the function twice is safe */
964 siphash_openssl(sipctx, ut_message, strlen(ut_message), ut_key, out,
966 assert_memory_equal(out, expected_hash, UT_SIPHASH_HASH_SIZE);
967
968 /* Test a few random strings and ensure that our implementation behave the
969 * same */
970 for (int i = 0; i < 1000; i++)
971 {
972 size_t len = random() % 1000u;
973 uint8_t buf[1024] = { 0 };
974 uint8_t key[SIPHASH_KEY_SIZE] = { 0 };
975
976 assert_true(rand_bytes(buf, (int)len));
977 assert_true(rand_bytes(key, sizeof(key)));
978
979
980 siphash_openssl(sipctx, buf, len, key, out, UT_SIPHASH_HASH_SIZE);
981
982 uint8_t outref[UT_SIPHASH_HASH_SIZE] = { 0 };
983 siphash_reference(buf, len, key, outref, UT_SIPHASH_HASH_SIZE);
984
985 assert_memory_equal(out, outref, UT_SIPHASH_HASH_SIZE);
986 }
987
989}
990
991
992int
993main(void)
994{
995 uint16_t prestate_num13 = 13;
996 uint16_t prestate_num16 = 16;
997 uint16_t prestate_num32 = 32;
998
1000 const struct CMUnitTest tests[] = {
1001 cmocka_unit_test(crypto_pem_encode_decode_loopback),
1002 cmocka_unit_test(crypto_translate_cipher_names),
1003 cmocka_unit_test(crypto_test_tls_prf),
1004 cmocka_unit_test(crypto_test_hmac),
1005 cmocka_unit_test(test_occ_mtu_calculation),
1006 cmocka_unit_test(test_mssfix_mtu_calculation),
1007 cmocka_unit_test(crypto_test_aead_limits),
1008 cmocka_unit_test(crypto_test_hkdf_expand_testa1),
1009 cmocka_unit_test(crypto_test_hkdf_expand_testa2),
1010 cmocka_unit_test(crypto_test_hkdf_expand_testa3),
1011 cmocka_unit_test(crypto_test_hkdf_expand_test_ovpn),
1012 cmocka_unit_test(crypto_test_ovpn_label_expand),
1013 cmocka_unit_test(crypto_test_ovpn_expand_openssl3),
1014 cmocka_unit_test_prestate_setup_teardown(crypto_test_epoch_key_generation,
1016 crypto_test_epoch_teardown, &prestate_num16),
1017 cmocka_unit_test_prestate_setup_teardown(crypto_test_epoch_key_rotation,
1019 crypto_test_epoch_teardown, &prestate_num13),
1020 cmocka_unit_test_prestate_setup_teardown(crypto_test_epoch_key_receive_lookup,
1022 crypto_test_epoch_teardown, &prestate_num13),
1023 cmocka_unit_test_prestate_setup_teardown(crypto_test_epoch_key_overflow,
1025 crypto_test_epoch_teardown, &prestate_num32),
1026 cmocka_unit_test_prestate_setup_teardown(crypto_test_epoch_edge,
1028 crypto_test_epoch_teardown, &prestate_num13),
1029 cmocka_unit_test(epoch_test_derive_data_key),
1030 cmocka_unit_test(test_siphash),
1031 cmocka_unit_test(test_siphash_openssl)
1032 };
1033
1034 return cmocka_run_group_tests_name("crypto tests", tests, NULL, NULL);
1035}
char * string_alloc(const char *str, struct gc_arena *gc)
Duplicate a string, allocating memory under garbage collection.
Definition buffer.c:616
#define BPTR(buf)
Return a pointer to the start of the buffer content.
Definition buffer.h:139
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Initialise a buffer with an externally provided writable memory region.
Definition buffer.h:594
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Initialise a buffer with an externally provided read-only memory region.
Definition buffer.h:623
#define BLEN(buf)
Return the length of the buffer content in bytes.
Definition buffer.h:145
#define BLENZ(buf)
Return the length of the buffer content as a size_t.
Definition buffer.h:147
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1912
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1896
#define COMP_ALG_LZO
LZO algorithm.
Definition comp.h:57
#define COMP_ALG_UNDEF
Definition comp.h:54
void free_key_ctx_bi(struct key_ctx_bi *ctx)
Definition crypto.c:1100
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.
Definition crypto.c:875
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...
Definition crypto.c:345
void free_key_ctx(struct key_ctx *ctx)
Definition crypto.c:1081
Data Channel Cryptography Module.
bool ssl_tls1_PRF(const uint8_t *seed, size_t seed_len, const uint8_t *secret, size_t secret_len, uint8_t *output, size_t output_len)
Calculates the TLS 1.0-1.1 PRF function.
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 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)
int rand_bytes(uint8_t *output, int len)
Wrapper for secure random number generator.
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.
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.
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, size_t out_len)
Variant of the RFC 8446 TLS 1.3 HKDF-Expand-Label function with the following differences/restriction...
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, size_t info_len, uint8_t *out, size_t 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.
#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.
Definition mss.c:317
size_t calc_options_string_link_mtu(const struct options *o, const struct frame *frame)
Calculate the link-mtu to advertise to our peer.
Definition mtu.c:155
void OSSL_LIB_CTX
#define CLEAR(x)
Definition basic.h:32
#define SIPHASH_KEY_SIZE
Definition siphash.h:35
void siphash_reference(const void *in, size_t inlen, const void *k, uint8_t *out, size_t outlen)
Calculates SIPHASH using the reference implementation.
bool siphash_openssl_available(void *sip_context)
Returns if the crypto library is available (and should be used)
void * siphash_openssl_init(size_t hash_size)
void siphash_openssl_uninit(void *sip_context)
Free the siphash context used for the crypto library.
int siphash_openssl(void *sip_context, const void *in, const size_t inlen, const void *k, uint8_t *out, const size_t outlen)
Calculates SIPHASH using the crypto library function.
@ PROTO_UDP
@ PROTO_TCP_CLIENT
Control Channel SSL library backend module.
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:76
int mssfix
Definition options.h:146
const char * socks_proxy_server
Definition options.h:125
int fragment
Definition options.h:143
int proto
Definition options.h:111
int tun_mtu
Definition options.h:129
Contains all state information for one tunnel.
Definition openvpn.h:471
Security parameter state for processing data channel packets.
Definition crypto.h:293
struct epoch_key epoch_key_send
last epoch_key used for generation of the current send data keys.
Definition crypto.h:303
struct key_ctx epoch_retiring_data_receive_key
The old key before the sender switched to a new epoch data key.
Definition crypto.h:330
struct key_ctx * epoch_data_keys_future
Keeps the future epoch data keys for decryption.
Definition crypto.h:324
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
Definition crypto.h:294
uint16_t epoch_data_keys_future_count
number of keys stored in epoch_data_keys_future
Definition crypto.h:327
struct epoch_key epoch_key_recv
epoch_key used for the highest receive epoch keys
Definition crypto.h:306
uint16_t epoch
Definition crypto.h:194
struct crypto_options co
struct key_type kt
struct gc_arena gc
Packet geometry parameters.
Definition mtu.h:113
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
Definition list.h:56
struct key_ctx decrypt
cipher and/or HMAC contexts for receiving direction.
Definition crypto.h:283
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
Definition crypto.h:281
Container for one set of cipher and/or HMAC contexts.
Definition crypto.h:202
uint16_t epoch
OpenVPN data channel epoch, this variable holds the epoch number this key belongs to.
Definition crypto.h:228
internal structure similar to struct key that holds key information but is not represented on wire an...
Definition crypto.h:163
unsigned int hmac_size
Number of bytes set in the HMac key material.
Definition crypto.h:174
uint8_t hmac[MAX_HMAC_KEY_LENGTH]
Key material for HMAC operations.
Definition crypto.h:171
uint8_t cipher[MAX_CIPHER_KEY_LENGTH]
Key material for cipher operations.
Definition crypto.h:165
unsigned int cipher_size
Number of bytes set in the cipher key material.
Definition crypto.h:168
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
struct compress_options comp
Definition options.h:410
const char * tls_auth_file
Definition options.h:660
bool use_peer_id
Whether the data channel uses the DATA_V2 header (peer-id).
Definition options.h:703
const char * authname
Definition options.h:581
uint32_t peer_id
Definition options.h:704
struct connection_entry ce
Definition options.h:294
const char * ciphername
Definition options.h:575
bool pull
Definition options.h:556
bool tls_client
Definition options.h:592
const char * shared_secret_file
Definition options.h:571
#define random
Definition syshead.h:43
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...
Definition test_common.h:61
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)
Definition test_crypto.c:98
static void test_siphash_openssl(void **state)
static void test_siphash(void **state)
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)
Definition test_crypto.c:82
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[]
Definition test_crypto.c:53
void crypto_test_epoch_edge(void **state)
static int crypto_test_epoch_teardown(void **state)
static const char * ut_message
static void crypto_test_hmac(void **state)
void crypto_test_aead_limits(void **state)
#define UT_SIPHASH_HASH_SIZE
int main(void)
static void crypto_pem_encode_decode_loopback(void **state)
Definition test_crypto.c:56
void crypto_test_epoch_key_generation(void **state)
static const char * ipsumlorem
const uint8_t expected_hash[UT_SIPHASH_HASH_SIZE]
static int crypto_test_epoch_setup(void **state)
void epoch_test_derive_data_key(void **state)
static const uint8_t ut_key[SIPHASH_KEY_SIZE]
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)
struct gc_arena gc
Definition test_ssl.c:122