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.
26 #elif defined(_MSC_VER)
27 #include "config-msvc.h"
41 #include "ssl_backend.h"
45 static const char testtext
[] = "Dummy text to test PEM encoding";
48 crypto_pem_encode_decode_loopback(void **state
)
50 struct gc_arena gc
= gc_new();
51 struct buffer src_buf
;
52 buf_set_read(&src_buf
, (void *)testtext
, sizeof(testtext
));
54 uint8_t dec
[sizeof(testtext
)];
55 struct buffer dec_buf
;
56 buf_set_write(&dec_buf
, dec
, sizeof(dec
));
58 struct buffer pem_buf
;
60 assert_true(crypto_pem_encode("TESTKEYNAME", &pem_buf
, &src_buf
, &gc
));
61 assert_true(BLEN(&src_buf
) < BLEN(&pem_buf
));
64 assert_false(crypto_pem_decode("WRONGNAME", &dec_buf
, &pem_buf
));
66 assert_true(crypto_pem_decode("TESTKEYNAME", &dec_buf
, &pem_buf
));
67 assert_int_equal(BLEN(&src_buf
), BLEN(&dec_buf
));
68 assert_memory_equal(BPTR(&src_buf
), BPTR(&dec_buf
), BLEN(&src_buf
));
74 test_translate_cipher(const char *ciphername
, const char *openvpn_name
)
76 bool cipher
= cipher_valid(ciphername
);
78 /* Empty cipher is fine */
84 const char *kt_name
= cipher_kt_name(ciphername
);
86 assert_string_equal(kt_name
, openvpn_name
);
90 test_cipher_names(const char *ciphername
, const char *openvpn_name
)
92 struct gc_arena gc
= gc_new();
93 /* Go through some variants, if the cipher library accepts these, they
94 * should be normalised to the openvpn name */
95 char *upper
= string_alloc(ciphername
, &gc
);
96 char *lower
= string_alloc(ciphername
, &gc
);
97 char *random_case
= string_alloc(ciphername
, &gc
);
99 for (int i
= 0; i
< strlen(ciphername
); i
++)
101 upper
[i
] = toupper(ciphername
[i
]);
102 lower
[i
] = tolower(ciphername
[i
]);
105 random_case
[i
] = upper
[i
];
109 random_case
[i
] = lower
[i
];
115 openvpn_name
= upper
;
118 test_translate_cipher(upper
, openvpn_name
);
119 test_translate_cipher(lower
, openvpn_name
);
120 test_translate_cipher(random_case
, openvpn_name
);
121 test_translate_cipher(ciphername
, openvpn_name
);
128 crypto_translate_cipher_names(void **state
)
130 /* Test that a number of ciphers to see that they turn out correctly */
131 test_cipher_names("BF-CBC", NULL
);
132 test_cipher_names("BLOWFISH-CBC", "BF-CBC");
133 test_cipher_names("Chacha20-Poly1305", NULL
);
134 test_cipher_names("AES-128-GCM", NULL
);
135 test_cipher_names("AES-128-CBC", NULL
);
136 test_cipher_names("CAMELLIA-128-CFB128", "CAMELLIA-128-CFB");
137 test_cipher_names("id-aes256-GCM", "AES-256-GCM");
141 static uint8_t good_prf
[32] = {0xd9, 0x8c, 0x85, 0x18, 0xc8, 0x5e, 0x94, 0x69,
142 0x27, 0x91, 0x6a, 0xcf, 0xc2, 0xd5, 0x92, 0xfb,
143 0xb1, 0x56, 0x7e, 0x4b, 0x4b, 0x14, 0x59, 0xe6,
144 0xa9, 0x04, 0xac, 0x2d, 0xda, 0xb7, 0x2d, 0x67};
146 static const char* ipsumlorem
= "Lorem ipsum dolor sit amet, consectetur "
147 "adipisici elit, sed eiusmod tempor incidunt "
148 "ut labore et dolore magna aliqua.";
151 crypto_test_tls_prf(void **state
)
153 const char *seedstr
= "Quis aute iure reprehenderit in voluptate "
154 "velit esse cillum dolore";
155 const unsigned char *seed
= (const unsigned char *)seedstr
;
156 const size_t seed_len
= strlen(seedstr
);
159 const unsigned char *secret
= (const unsigned char *) ipsumlorem
;
160 size_t secret_len
= strlen((const char *)secret
);
164 ssl_tls1_PRF(seed
, seed_len
, secret
, secret_len
, out
, sizeof(out
));
166 assert_memory_equal(good_prf
, out
, sizeof(out
));
169 static uint8_t testkey
[20] = {0x0b, 0x00};
170 static uint8_t goodhash
[20] = {0x58, 0xea, 0x5a, 0xf0, 0x42, 0x94, 0xe9, 0x17,
171 0xed, 0x84, 0xb9, 0xf0, 0x83, 0x30, 0x23, 0xae,
172 0x8b, 0xa7, 0x7e, 0xb8};
175 crypto_test_hmac(void **state
)
177 hmac_ctx_t
*hmac
= hmac_ctx_new();
179 assert_int_equal(md_kt_size("SHA1"), 20);
182 memcpy(key
, testkey
, sizeof(key
));
184 hmac_ctx_init(hmac
, key
, "SHA1");
185 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
186 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
189 hmac_ctx_final(hmac
, hash
);
191 assert_memory_equal(hash
, goodhash
, sizeof(hash
));
192 memset(hash
, 0x00, sizeof(hash
));
195 hmac_ctx_reset(hmac
);
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 hmac_ctx_final(hmac
, hash
);
200 assert_memory_equal(hash
, goodhash
, sizeof(hash
));
202 /* Fill our key with random data to ensure it is not used by hmac anymore */
203 memset(key
, 0x55, sizeof(key
));
205 hmac_ctx_reset(hmac
);
206 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
207 hmac_ctx_update(hmac
, (const uint8_t *)ipsumlorem
, (int) strlen(ipsumlorem
));
208 hmac_ctx_final(hmac
, hash
);
210 assert_memory_equal(hash
, goodhash
, sizeof(hash
));
211 hmac_ctx_cleanup(hmac
);
216 test_des_encrypt(void **state
)
218 /* We have a small des encrypt method that is only for NTLMv1. This unit
219 * test ensures that it is not accidentally broken */
221 const unsigned char des_key
[DES_KEY_LENGTH
] = {0x42, 0x23};
223 const char *src
= "MoinWelt";
225 /* cipher_des_encrypt_ecb wants a non const */
226 unsigned char *src2
= (unsigned char *) strdup(src
);
228 unsigned char dst
[DES_KEY_LENGTH
];
229 cipher_des_encrypt_ecb(des_key
, src2
, dst
);
231 const unsigned char dst_good
[DES_KEY_LENGTH
] = {0xd3, 0x8f, 0x61, 0xf7, 0xbe, 0x27, 0xb6, 0xa2};
233 assert_memory_equal(dst
, dst_good
, DES_KEY_LENGTH
);
238 /* This test is in test_crypto as it calls into the functions that calculate
239 * the crypto overhead */
241 test_occ_mtu_calculation(void **state
)
243 struct gc_arena gc
= gc_new();
245 struct frame f
= { 0 };
246 struct options o
= { 0 };
249 /* common defaults */
252 o
.ce
.proto
= PROTO_UDP
;
254 /* No crypto at all */
255 o
.ciphername
= "none";
257 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
258 assert_int_equal(linkmtu
, 1400);
260 /* Static key OCC examples */
261 o
.shared_secret_file
= "not null";
263 /* secret, auth none, cipher none */
264 o
.ciphername
= "none";
266 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
267 assert_int_equal(linkmtu
, 1408);
269 /* secret, cipher AES-128-CBC, auth none */
270 o
.ciphername
= "AES-128-CBC";
272 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
273 assert_int_equal(linkmtu
, 1440);
275 /* secret, cipher none, auth SHA256 */
276 o
.ciphername
= "none";
277 o
.authname
= "SHA256";
278 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
279 assert_int_equal(linkmtu
, 1440);
281 /* secret, cipher BF-CBC, auth SHA1 */
282 o
.ciphername
= "BF-CBC";
284 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
285 assert_int_equal(linkmtu
, 1444);
287 /* secret, cipher BF-CBC, auth SHA1, tcp-client */
288 o
.ce
.proto
= PROTO_TCP_CLIENT
;
289 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
290 assert_int_equal(linkmtu
, 1446);
292 o
.ce
.proto
= PROTO_UDP
;
294 #if defined(USE_COMP)
295 o
.comp
.alg
= COMP_ALG_LZO
;
297 /* secret, comp-lzo yes, cipher BF-CBC, auth SHA1 */
298 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
299 assert_int_equal(linkmtu
, 1445);
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);
306 o
.comp
.alg
= COMP_ALG_UNDEF
;
311 o
.shared_secret_file
= NULL
;
315 /* tls client, cipher AES-128-CBC, auth SHA1, tls-auth */
317 o
.ciphername
= "AES-128-CBC";
318 o
.tls_auth_file
= "dummy";
320 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
321 assert_int_equal(linkmtu
, 1457);
323 /* tls client, cipher AES-128-CBC, auth SHA1 */
324 o
.tls_auth_file
= NULL
;
326 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
327 assert_int_equal(linkmtu
, 1457);
329 /* tls client, cipher none, auth none */
331 o
.ciphername
= "none";
333 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
334 assert_int_equal(linkmtu
, 1405);
336 /* tls client, auth none, cipher none, no-replay */
339 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
340 assert_int_equal(linkmtu
, 1401);
345 /* tls client, auth SHA1, cipher AES-256-GCM */
347 o
.ciphername
= "AES-256-GCM";
348 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
349 assert_int_equal(linkmtu
, 1449);
352 #if defined(USE_COMP)
353 o
.comp
.alg
= COMP_ALG_LZO
;
355 /* tls client, auth SHA1, cipher AES-256-GCM, fragment, comp-lzo yes */
356 o
.ce
.fragment
= 1200;
357 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
358 assert_int_equal(linkmtu
, 1454);
360 /* tls client, auth SHA1, cipher AES-256-GCM, fragment, comp-lzo yes, socks */
361 o
.ce
.socks_proxy_server
= "socks.example.com";
362 linkmtu
= calc_options_string_link_mtu(&o
, &f
);
363 assert_int_equal(linkmtu
, 1464);
372 const struct CMUnitTest tests
[] = {
373 cmocka_unit_test(crypto_pem_encode_decode_loopback
),
374 cmocka_unit_test(crypto_translate_cipher_names
),
375 cmocka_unit_test(crypto_test_tls_prf
),
376 cmocka_unit_test(crypto_test_hmac
),
377 cmocka_unit_test(test_des_encrypt
),
378 cmocka_unit_test(test_occ_mtu_calculation
)
381 #if defined(ENABLE_CRYPTO_OPENSSL)
382 OpenSSL_add_all_algorithms();
385 int ret
= cmocka_run_group_tests_name("crypto tests", tests
, NULL
, NULL
);
387 #if defined(ENABLE_CRYPTO_OPENSSL)