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
8 * Copyright (C) 2016-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
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.
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.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
39 #include "ssl_backend.h"
44 static const char testtext
[] = "Dummy text to test PEM encoding";
47 crypto_pem_encode_decode_loopback(void **state
)
49 struct gc_arena gc
= gc_new();
50 struct buffer src_buf
;
51 buf_set_read(&src_buf
, (void *)testtext
, sizeof(testtext
));
53 uint8_t dec
[sizeof(testtext
)];
54 struct buffer dec_buf
;
55 buf_set_write(&dec_buf
, dec
, sizeof(dec
));
57 struct buffer pem_buf
;
59 assert_true(crypto_pem_encode("TESTKEYNAME", &pem_buf
, &src_buf
, &gc
));
60 assert_true(BLEN(&src_buf
) < BLEN(&pem_buf
));
63 assert_false(crypto_pem_decode("WRONGNAME", &dec_buf
, &pem_buf
));
65 assert_true(crypto_pem_decode("TESTKEYNAME", &dec_buf
, &pem_buf
));
66 assert_int_equal(BLEN(&src_buf
), BLEN(&dec_buf
));
67 assert_memory_equal(BPTR(&src_buf
), BPTR(&dec_buf
), BLEN(&src_buf
));
73 test_translate_cipher(const char *ciphername
, const char *openvpn_name
)
75 bool cipher
= cipher_valid(ciphername
);
77 /* Empty cipher is fine */
83 const char *kt_name
= cipher_kt_name(ciphername
);
85 assert_string_equal(kt_name
, openvpn_name
);
89 test_cipher_names(const char *ciphername
, const char *openvpn_name
)
91 struct gc_arena gc
= gc_new();
92 /* Go through some variants, if the cipher library accepts these, they
93 * should be normalised to the openvpn name */
94 char *upper
= string_alloc(ciphername
, &gc
);
95 char *lower
= string_alloc(ciphername
, &gc
);
96 char *random_case
= string_alloc(ciphername
, &gc
);
98 for (int i
= 0; i
< strlen(ciphername
); i
++)
100 upper
[i
] = toupper(ciphername
[i
]);
101 lower
[i
] = tolower(ciphername
[i
]);
104 random_case
[i
] = upper
[i
];
108 random_case
[i
] = lower
[i
];
114 openvpn_name
= upper
;
117 test_translate_cipher(upper
, openvpn_name
);
118 test_translate_cipher(lower
, openvpn_name
);
119 test_translate_cipher(random_case
, openvpn_name
);
120 test_translate_cipher(ciphername
, openvpn_name
);
127 crypto_translate_cipher_names(void **state
)
129 /* Test that a number of ciphers to see that they turn out correctly */
130 test_cipher_names("BF-CBC", NULL
);
131 test_cipher_names("BLOWFISH-CBC", "BF-CBC");
132 test_cipher_names("Chacha20-Poly1305", NULL
);
133 test_cipher_names("AES-128-GCM", NULL
);
134 test_cipher_names("AES-128-CBC", NULL
);
135 test_cipher_names("CAMELLIA-128-CFB128", "CAMELLIA-128-CFB");
136 test_cipher_names("id-aes256-GCM", "AES-256-GCM");
140 static uint8_t good_prf
[32] = {0xd9, 0x8c, 0x85, 0x18, 0xc8, 0x5e, 0x94, 0x69,
141 0x27, 0x91, 0x6a, 0xcf, 0xc2, 0xd5, 0x92, 0xfb,
142 0xb1, 0x56, 0x7e, 0x4b, 0x4b, 0x14, 0x59, 0xe6,
143 0xa9, 0x04, 0xac, 0x2d, 0xda, 0xb7, 0x2d, 0x67};
145 static const char *ipsumlorem
= "Lorem ipsum dolor sit amet, consectetur "
146 "adipisici elit, sed eiusmod tempor incidunt "
147 "ut labore et dolore magna aliqua.";
150 crypto_test_tls_prf(void **state
)
152 const char *seedstr
= "Quis aute iure reprehenderit in voluptate "
153 "velit esse cillum dolore";
154 const unsigned char *seed
= (const unsigned char *)seedstr
;
155 const size_t seed_len
= strlen(seedstr
);
158 const unsigned char *secret
= (const unsigned char *) ipsumlorem
;
159 size_t secret_len
= strlen((const char *)secret
);
163 ssl_tls1_PRF(seed
, seed_len
, secret
, secret_len
, out
, sizeof(out
));
165 assert_memory_equal(good_prf
, out
, sizeof(out
));
168 static uint8_t testkey
[20] = {0x0b, 0x00};
169 static uint8_t goodhash
[20] = {0x58, 0xea, 0x5a, 0xf0, 0x42, 0x94, 0xe9, 0x17,
170 0xed, 0x84, 0xb9, 0xf0, 0x83, 0x30, 0x23, 0xae,
171 0x8b, 0xa7, 0x7e, 0xb8};
174 crypto_test_hmac(void **state
)
176 hmac_ctx_t
*hmac
= hmac_ctx_new();
178 assert_int_equal(md_kt_size("SHA1"), 20);
181 memcpy(key
, testkey
, sizeof(key
));
183 hmac_ctx_init(hmac
, key
, "SHA1");
184 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
185 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
188 hmac_ctx_final(hmac
, hash
);
190 assert_memory_equal(hash
, goodhash
, sizeof(hash
));
191 memset(hash
, 0x00, sizeof(hash
));
194 hmac_ctx_reset(hmac
);
195 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
196 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
197 hmac_ctx_final(hmac
, hash
);
199 assert_memory_equal(hash
, goodhash
, sizeof(hash
));
201 /* Fill our key with random data to ensure it is not used by hmac anymore */
202 memset(key
, 0x55, sizeof(key
));
204 hmac_ctx_reset(hmac
);
205 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
206 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
207 hmac_ctx_final(hmac
, hash
);
209 assert_memory_equal(hash
, goodhash
, sizeof(hash
));
210 hmac_ctx_cleanup(hmac
);
215 test_des_encrypt(void **state
)
217 /* We have a small des encrypt method that is only for NTLMv1. This unit
218 * test ensures that it is not accidentally broken */
220 const unsigned char des_key
[DES_KEY_LENGTH
] = {0x42, 0x23};
222 const char *src
= "MoinWelt";
224 /* cipher_des_encrypt_ecb wants a non const */
225 unsigned char *src2
= (unsigned char *) strdup(src
);
227 unsigned char dst
[DES_KEY_LENGTH
];
228 cipher_des_encrypt_ecb(des_key
, src2
, dst
);
230 const unsigned char dst_good
[DES_KEY_LENGTH
] = {0xd3, 0x8f, 0x61, 0xf7, 0xbe, 0x27, 0xb6, 0xa2};
232 assert_memory_equal(dst
, dst_good
, DES_KEY_LENGTH
);
237 /* This test is in test_crypto as it calls into the functions that calculate
238 * the crypto overhead */
240 test_occ_mtu_calculation(void **state
)
242 struct gc_arena gc
= gc_new();
244 struct frame f
= { 0 };
245 struct options o
= { 0 };
248 /* common defaults */
251 o
.ce
.proto
= PROTO_UDP
;
253 /* No crypto at all */
254 o
.ciphername
= "none";
256 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
257 assert_int_equal(linkmtu
, 1400);
259 /* Static key OCC examples */
260 o
.shared_secret_file
= "not null";
262 /* secret, auth none, cipher none */
263 o
.ciphername
= "none";
265 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
266 assert_int_equal(linkmtu
, 1408);
268 /* secret, cipher AES-128-CBC, auth none */
269 o
.ciphername
= "AES-128-CBC";
271 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
272 assert_int_equal(linkmtu
, 1440);
274 /* secret, cipher none, auth SHA256 */
275 o
.ciphername
= "none";
276 o
.authname
= "SHA256";
277 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
278 assert_int_equal(linkmtu
, 1440);
280 /* secret, cipher BF-CBC, auth SHA1 */
281 o
.ciphername
= "BF-CBC";
283 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
284 assert_int_equal(linkmtu
, 1444);
286 /* secret, cipher BF-CBC, auth SHA1, tcp-client */
287 o
.ce
.proto
= PROTO_TCP_CLIENT
;
288 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
289 assert_int_equal(linkmtu
, 1446);
291 o
.ce
.proto
= PROTO_UDP
;
293 #if defined(USE_COMP)
294 o
.comp
.alg
= COMP_ALG_LZO
;
296 /* secret, comp-lzo yes, cipher BF-CBC, auth SHA1 */
297 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
298 assert_int_equal(linkmtu
, 1445);
300 #if defined(ENABLE_FRAGMENT)
301 /* secret, comp-lzo yes, cipher BF-CBC, auth SHA1, fragment 1200 */
302 o
.ce
.fragment
= 1200;
303 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
304 assert_int_equal(linkmtu
, 1449);
308 o
.comp
.alg
= COMP_ALG_UNDEF
;
312 o
.shared_secret_file
= NULL
;
316 /* tls client, cipher AES-128-CBC, auth SHA1, tls-auth */
318 o
.ciphername
= "AES-128-CBC";
319 o
.tls_auth_file
= "dummy";
321 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
322 assert_int_equal(linkmtu
, 1457);
324 /* tls client, cipher AES-128-CBC, auth SHA1 */
325 o
.tls_auth_file
= NULL
;
327 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
328 assert_int_equal(linkmtu
, 1457);
330 /* tls client, cipher none, auth none */
332 o
.ciphername
= "none";
334 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
335 assert_int_equal(linkmtu
, 1405);
337 /* tls client, auth none, cipher none, no-replay */
340 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
341 assert_int_equal(linkmtu
, 1401);
346 /* tls client, auth SHA1, cipher AES-256-GCM */
348 o
.ciphername
= "AES-256-GCM";
349 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
350 assert_int_equal(linkmtu
, 1449);
353 #if defined(USE_COMP) && defined(ENABLE_FRAGMENT)
354 o
.comp
.alg
= COMP_ALG_LZO
;
356 /* tls client, auth SHA1, cipher AES-256-GCM, fragment, comp-lzo yes */
357 o
.ce
.fragment
= 1200;
358 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
359 assert_int_equal(linkmtu
, 1454);
361 /* tls client, auth SHA1, cipher AES-256-GCM, fragment, comp-lzo yes, socks */
362 o
.ce
.socks_proxy_server
= "socks.example.com";
363 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
364 assert_int_equal(linkmtu
, 1464);
371 test_mssfix_mtu_calculation(void **state
)
373 struct gc_arena gc
= gc_new();
375 struct frame f
= { 0 };
376 struct options o
= { 0 };
378 /* common defaults */
382 o
.ce
.proto
= PROTO_UDP
;
384 /* No crypto at all */
385 o
.ciphername
= "none";
388 init_key_type(&kt
, o
.ciphername
, o
.authname
, false, false);
390 /* No encryption, just packet id (8) + TCP payload(20) + IP payload(20) */
391 frame_calculate_dynamic(&f
, &kt
, &o
, NULL
);
392 assert_int_equal(f
.mss_fix
, 952);
394 /* Static key OCC examples */
395 o
.shared_secret_file
= "not null";
397 /* secret, auth none, cipher none */
398 o
.ciphername
= "none";
400 init_key_type(&kt
, o
.ciphername
, o
.authname
, false, false);
401 frame_calculate_dynamic(&f
, &kt
, &o
, NULL
);
402 assert_int_equal(f
.mss_fix
, 952);
404 /* secret, cipher AES-128-CBC, auth none */
405 o
.ciphername
= "AES-128-CBC";
407 init_key_type(&kt
, o
.ciphername
, o
.authname
, false, false);
409 for (int i
= 990; i
<= 1010; i
++)
411 /* 992 - 1008 should end up with the same mssfix value all they
412 * all result in the same CBC block size/padding and <= 991 and >=1008
413 * should be one block less and more respectively */
415 frame_calculate_dynamic(&f
, &kt
, &o
, NULL
);
418 assert_int_equal(f
.mss_fix
, 911);
422 assert_int_equal(f
.mss_fix
, 943);
426 assert_int_equal(f
.mss_fix
, 927);
430 o
.comp
.alg
= COMP_ALG_LZO
;
432 /* Same but with compression added. Compression adds one byte extra to the
433 * payload so the payload should be reduced by compared to the no
434 * compression calculation before */
435 for (int i
= 990; i
<= 1010; i
++)
437 /* 992 - 1008 should end up with the same mssfix value all they
438 * all result in the same CBC block size/padding and <= 991 and >=1008
439 * should be one block less and more respectively */
441 frame_calculate_dynamic(&f
, &kt
, &o
, NULL
);
444 assert_int_equal(f
.mss_fix
, 910);
448 assert_int_equal(f
.mss_fix
, 942);
452 assert_int_equal(f
.mss_fix
, 926);
455 o
.comp
.alg
= COMP_ALG_UNDEF
;
456 #endif /* ifdef USE_COMP */
458 /* tls client, auth SHA1, cipher AES-256-GCM */
460 o
.ciphername
= "AES-256-GCM";
463 o
.use_peer_id
= true;
464 init_key_type(&kt
, o
.ciphername
, o
.authname
, true, false);
466 for (int i
= 900; i
<= 1200; i
++)
468 /* For stream ciphers, the value should not be influenced by block
469 * sizes or similar but always have the same difference */
471 frame_calculate_dynamic(&f
, &kt
, &o
, NULL
);
473 /* 4 byte opcode/peerid, 4 byte pkt ID, 16 byte tag, 40 TCP+IP */
474 assert_int_equal(f
.mss_fix
, i
- 4 - 4 - 16 - 40);
483 const struct CMUnitTest tests
[] = {
484 cmocka_unit_test(crypto_pem_encode_decode_loopback
),
485 cmocka_unit_test(crypto_translate_cipher_names
),
486 cmocka_unit_test(crypto_test_tls_prf
),
487 cmocka_unit_test(crypto_test_hmac
),
488 cmocka_unit_test(test_des_encrypt
),
489 cmocka_unit_test(test_occ_mtu_calculation
),
490 cmocka_unit_test(test_mssfix_mtu_calculation
)
493 #if defined(ENABLE_CRYPTO_OPENSSL)
494 OpenSSL_add_all_algorithms();
497 int ret
= cmocka_run_group_tests_name("crypto tests", tests
, NULL
, NULL
);
499 #if defined(ENABLE_CRYPTO_OPENSSL)