149 openvpn::CryptoAlgs::allow_default_dc_algs<openvpn::SSLLib::CryptoAPI>(
nullptr,
true,
false);
154 const char *plaintext =
"The quick little fox jumps over the bureaucratic hurdles";
161 std::memcpy(
work.write_alloc(std::strlen(plaintext)), plaintext, std::strlen(plaintext));
162 const unsigned char *data =
work.data();
163 EXPECT_TRUE(std::memcmp(data, plaintext, std::strlen(plaintext)) == 0);
165 const std::time_t now = 42;
167 const unsigned char op32[]{7, 0, 0, 23};
169 bool const wrapwarn = cryptodc->
encrypt(
work, op32);
170 ASSERT_FALSE(wrapwarn);
172 size_t pkt_counter_len = use_epoch ? 8 : 4;
176 EXPECT_EQ(
work.size(), std::strlen(plaintext) + pkt_counter_len + tag_len);
178 const uint8_t exp_tag_short[16]{0x1f, 0xdd, 0x90, 0x8f, 0x0e, 0x9d, 0xc2, 0x5e, 0x79, 0xd8, 0x32, 0x02, 0x0d, 0x58, 0xe7, 0x3f};
179 std::array<uint8_t, 16> exp_tag_epoch = {0Xa0, 0xb5, 0x4c, 0xdd, 0x93, 0xff, 0x0b, 0x01, 0xa3, 0x26, 0x5e, 0xcf, 0x19, 0xd5, 0x6a, 0x06};
183 ptrdiff_t tag_offset = 56;
184 uint8_t packetid1[8] = {0, 0x1, 0, 0, 0, 0, 0, 1};
185 EXPECT_EQ(std::memcmp(
work.data(), packetid1, 8), 0);
189 std::array<uint8_t, 16> tag{};
190 std::memcpy(tag.data(),
work.data() + tag_offset + pkt_counter_len, 16);
191 EXPECT_EQ(tag, exp_tag_epoch);
194 const uint8_t bytesat14[6]{0x8e, 0x45, 0x5a, 0xdd, 0xd9, 0x0e};
195 EXPECT_EQ(std::memcmp(
work.data() + 14, bytesat14, 6), 0);
199 ptrdiff_t tag_offset = 16;
200 uint8_t packetid1[]{0, 0, 0, 1};
201 EXPECT_EQ(std::memcmp(
work.data(), packetid1, 4), 0);
202 EXPECT_EQ(std::memcmp(
work.data() + pkt_counter_len, exp_tag_short, 16), 0);
205 const uint8_t bytesat14[6]{0xa8, 0x2e, 0x6b, 0x17, 0x06, 0xd9};
206 EXPECT_EQ(std::memcmp(
work.data() + tag_offset + 14, bytesat14, 6), 0);
213 EXPECT_EQ(
work.size(), std::strlen(plaintext));
215 EXPECT_EQ(std::memcmp(
work.data(), plaintext, std::strlen(plaintext)), 0);
218TEST(crypto, testEpochIterateKey)
220 openvpn::CryptoAlgs::allow_default_dc_algs<openvpn::SSLLib::CryptoAPI>(
nullptr,
true,
false);
227 ASSERT_NE(epochdcsend,
nullptr);
230 epochdcsend->increase_send_epoch();
231 epochdcsend->increase_send_epoch();
232 epochdcsend->increase_send_epoch();
234 const char *plaintext =
"The quick little fox jumps over the bureaucratic hurdles";
236 const std::time_t now = 42;
238 const unsigned char op32[]{7, 0, 0, 23};
245 std::memcpy(
work.write_alloc(std::strlen(plaintext)), plaintext, std::strlen(plaintext));
247 bool const wrapwarn = cryptodcsend->
encrypt(
work, op32);
248 ASSERT_FALSE(wrapwarn);
250 std::size_t pkt_counter_len = 8;
251 std::size_t tag_len = 16;
254 EXPECT_EQ(
work.size(), std::strlen(plaintext) + pkt_counter_len + tag_len);
256 std::array<uint8_t, 16> exp_tag_epoch = {0x0f, 0xff, 0xf5, 0x91, 0x3d, 0x39, 0xd7, 0x5b, 0x18, 0x57, 0x3b, 0x57, 0x48, 0x58, 0x9a, 0x7d};
257 ptrdiff_t tag_offset = 56;
258 uint8_t packetid1[8] = {0, 0x4, 0, 0, 0, 0, 0, 1};
259 EXPECT_EQ(std::memcmp(
work.data(), packetid1, 8), 0);
262 std::array<uint8_t, 16> tag{};
263 std::memcpy(tag.data(),
work.data() + tag_offset + pkt_counter_len, 16);
264 EXPECT_EQ(tag, exp_tag_epoch);
267 const uint8_t bytesat14[6]{0x36, 0xaa, 0xb4, 0xd4, 0x9c, 0xe6};
268 EXPECT_EQ(std::memcmp(
work.data() + 14, bytesat14, 6), 0);
274 EXPECT_EQ(
work.size(), std::strlen(plaintext));
276 EXPECT_EQ(std::memcmp(
work.data(), plaintext, std::strlen(plaintext)), 0);
279TEST(crypto, epoch_derive_data_keys)
281 uint8_t epoch_key[32] = {19, 12};
288 auto [key, iv] = epoch.
data_key(cipher);
290 ASSERT_EQ(key.size(), 24);
291 ASSERT_EQ(iv.size(), 12);
293 std::array<uint8_t, 24> exp_key{0xed, 0x85, 0x33, 0xdb, 0x1c, 0x28, 0xac, 0xe4, 0x18, 0xe9, 0x00, 0x6a, 0xb2, 0x9c, 0x17, 0x41, 0x7d, 0x60, 0xeb, 0xe6, 0xcd, 0x90, 0xbf, 0x0a};
295 std::array<uint8_t, 12> exp_impl_iv{0x86, 0x89, 0x0a, 0xab, 0xf0, 0x32, 0xcb, 0x59, 0xf4, 0xcf, 0xa3, 0x4e};
298 std::array<uint8_t, 24> key_array;
299 std::array<uint8_t, 12> iv_array;
301 std::memcpy(key_array.data(), key.data(), key.size());
302 std::memcpy(iv_array.data(), iv.data(), iv.size());
304 EXPECT_EQ(exp_key, key_array);
305 EXPECT_EQ(exp_impl_iv, iv_array);
308TEST(crypto, aead_cipher_movable)
310 openvpn::CryptoAlgs::allow_default_dc_algs<openvpn::SSLLib::CryptoAPI>(
nullptr,
true,
false);
312 const uint8_t key[32] = {
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'j',
'k',
'u',
'c',
'h',
'e',
'n',
'l'};
314 openvpn::SSLLib::CryptoAPI::CipherContextAEAD cipher;
316 ASSERT_TRUE(cipher.is_initialized());
317 const uint8_t
input[5] = {
'h',
'e',
'l',
'l',
'o'};
318 uint8_t encrypted[64] = {0};
319 const uint8_t iv[12] = {0x77};
320 uint8_t *tag = encrypted +
sizeof(
input);
322 cipher.encrypt(
input, encrypted, 5, iv, tag,
nullptr, 0);
325 openvpn::SSLLib::CryptoAPI::CipherContextAEAD cipher2(std::move(cipher));
326 ASSERT_TRUE(cipher2.is_initialized());
327 ASSERT_FALSE(cipher.is_initialized());
329 uint8_t output2[32] = {0};
331 auto ret = cipher2.decrypt(encrypted, output2, 5 + openvpn::SSLLib::CryptoAPI::CipherContextAEAD::AUTH_TAG_LEN, iv,
nullptr,
nullptr, 0);
334 ASSERT_EQ(std::memcmp(
input, output2, 5), 0);
337 uint8_t output3[32] = {0};
339 openvpn::SSLLib::CryptoAPI::CipherContextAEAD cipher3;
340 cipher3 = std::move(cipher2);
341 ASSERT_TRUE(cipher3.is_initialized());
342 ASSERT_FALSE(cipher2.is_initialized());
343 ASSERT_FALSE(cipher.is_initialized());
345 ret = cipher3.decrypt(encrypted, output3, 5 + openvpn::SSLLib::CryptoAPI::CipherContextAEAD::AUTH_TAG_LEN, iv,
nullptr,
nullptr, 0);
348 ASSERT_EQ(std::memcmp(
input, output3, 5), 0);
362TEST(crypto, hkdf_expand_testa1)
367 {0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
368 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
369 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
370 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
373 {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
374 0xf6, 0xf7, 0xf8, 0xf9};
376 std::array<uint8_t,42> okm
377 {0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
378 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
379 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
380 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
381 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
386 std::array<uint8_t, 42>
out{};
392TEST(crypto, hkdf_expand_testa2)
397 {0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a,
398 0x06, 0x10, 0x4c, 0x9c, 0xeb, 0x35, 0xb4, 0x5c,
399 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01,
400 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44};
403 {0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
404 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
405 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
406 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
407 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
408 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
409 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
410 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
411 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
412 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
415 std::array<uint8_t,82> okm
416 {0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
417 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
418 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
419 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
420 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
421 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
422 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
423 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
424 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
425 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
429 ASSERT_EQ(L, okm.size());
430 std::array<uint8_t, 82>
out = {0xaa};
437TEST(crypto, ovpn_label_expand_test)
441 {0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
442 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
443 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
444 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
446 std::array<uint8_t, 16> out_expected =
447 {0x18, 0x5e, 0xaa, 0x1c, 0x7f, 0x22, 0x8a, 0xb8,
448 0xeb, 0x29, 0x77, 0x32, 0x14, 0xd9, 0x20, 0x46};
451 const uint8_t *label =
reinterpret_cast<const uint8_t *
>(
"unit test");
452 std::array<uint8_t, 16>
out;
455 EXPECT_EQ(
out, out_expected);
458TEST(crypto, hkdf_expand_testa3)
463 {0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16,
464 0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
465 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
466 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04};
468 std::array<uint8_t,42> okm =
469 {0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
470 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
471 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
472 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
473 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
477 uint8_t *info =
nullptr;
480 std::array<uint8_t,42>
out {0xfa};
557 dce_.replace_update_recv_key(9, stats);
559 EXPECT_EQ(dce_.recv_ctx_().epoch, 9);
560 EXPECT_EQ(dce_.send_ctx_().epoch, 9);
561 EXPECT_EQ(dce_.retire_().epoch, 1);
565 for (
int i = 0; i < 4; i++)
567 dce_.iterate_send_key();
570 EXPECT_EQ(dce_.send_ctx_().epoch, 13);
571EXPECT_EQ(dce_.send_().epoch, 13);
574EXPECT_EQ(dce_.recv_ctx_().epoch, 9);
576 dce_.replace_update_recv_key(10, stats);
578EXPECT_EQ(dce_.recv_ctx_().epoch, 10);
579EXPECT_EQ(dce_.send_ctx_().epoch, 13);
580 EXPECT_EQ(dce_.send_().epoch, 13);
582EXPECT_EQ(dce_.retire_().epoch, 9);
584dce_.replace_update_recv_key(12, stats);
585EXPECT_EQ(dce_.recv_ctx_().epoch, 12);
586EXPECT_EQ(dce_.send_ctx_().epoch, 13);
587EXPECT_EQ(dce_.send_().epoch, 13);
589EXPECT_EQ(dce_.retire_().epoch, 10);
591dce_.iterate_send_key();
592EXPECT_EQ(dce_.send_ctx_().epoch, 14);
600 EXPECT_EQ(dce_.lookup_decrypt_key(2000),
nullptr);
601 EXPECT_EQ(dce_.lookup_decrypt_key(-1),
nullptr);
602 EXPECT_EQ(dce_.lookup_decrypt_key(0xefff),
nullptr);
605 EXPECT_EQ(dce_.lookup_decrypt_key(0),
nullptr);
606 EXPECT_EQ(dce_.lookup_decrypt_key(1)->epoch, 1);
607 EXPECT_EQ(dce_.lookup_decrypt_key(2)->epoch, 2);
608 EXPECT_EQ(dce_.lookup_decrypt_key(13)->epoch, 13);
609 EXPECT_EQ(dce_.lookup_decrypt_key(14)->epoch, 14);
610 EXPECT_EQ(dce_.lookup_decrypt_key(15),
nullptr);
614 dce_.replace_update_recv_key(7, stats);
616 EXPECT_EQ(dce_.lookup_decrypt_key(0),
nullptr);
617 EXPECT_EQ(dce_.lookup_decrypt_key(1)->epoch, 1);
618 EXPECT_EQ(dce_.lookup_decrypt_key(2),
nullptr);
619 EXPECT_EQ(dce_.lookup_decrypt_key(3),
nullptr);
620 EXPECT_EQ(dce_.lookup_decrypt_key(4),
nullptr);
621 EXPECT_EQ(dce_.lookup_decrypt_key(5),
nullptr);
622 EXPECT_EQ(dce_.lookup_decrypt_key(6),
nullptr);
623 EXPECT_EQ(dce_.lookup_decrypt_key( 7)->epoch, 7);
624 EXPECT_EQ(dce_.lookup_decrypt_key( 8)->epoch, 8);
625 EXPECT_EQ(dce_.lookup_decrypt_key( 20)->epoch, 20);
626 EXPECT_EQ(dce_.lookup_decrypt_key(21),
nullptr);
627 EXPECT_EQ(dce_.lookup_decrypt_key(22),
nullptr);
632dce_.replace_update_recv_key(8, stats);
633 EXPECT_EQ(dce_.lookup_decrypt_key(0),
nullptr);
634 EXPECT_EQ(dce_.lookup_decrypt_key(1),
nullptr);
635 EXPECT_EQ(dce_.lookup_decrypt_key(2),
nullptr);
636 EXPECT_EQ(dce_.lookup_decrypt_key(3),
nullptr);
637 EXPECT_EQ(dce_.lookup_decrypt_key(4),
nullptr);
638 EXPECT_EQ(dce_.lookup_decrypt_key(5),
nullptr);
639 EXPECT_EQ(dce_.lookup_decrypt_key(6),
nullptr);
640 EXPECT_EQ(dce_.lookup_decrypt_key( 7)->epoch, 7);
641 EXPECT_EQ(dce_.lookup_decrypt_key( 8)->epoch, 8);
642 EXPECT_EQ(dce_.lookup_decrypt_key( 20)->epoch, 20);
643 EXPECT_EQ(dce_.lookup_decrypt_key( 21)->epoch, 21);
644 EXPECT_EQ(dce_.lookup_decrypt_key(22),
nullptr);
645 EXPECT_EQ(dce_.lookup_decrypt_key(23),
nullptr);
656 dce_.recv_ctx_().epoch = 16000;
657 dce_.send_ctx_().epoch = 16000;
659 dce_.send_().epoch = 16000;
660 dce_.recv_().epoch = 16000 + dce_.get_future_keys_count();
662 for (uint16_t i = 0; i < dce_.get_future_keys_count(); i++)
664 dce_.get_future_key(i).epoch = 16001 + i;
668 while (dce_.recv_ctx_().epoch < (UINT16_MAX - 40))
670 dce_.replace_update_recv_key(dce_.recv_ctx_().epoch + 10, stats);
675 EXPECT_EQ(dce_.lookup_decrypt_key( UINT16_MAX - 34)->epoch, UINT16_MAX - 34);
676 EXPECT_EQ(dce_.lookup_decrypt_key( UINT16_MAX - 33)->epoch, UINT16_MAX - 33);
680 EXPECT_EQ(dce_.lookup_decrypt_key(UINT16_MAX - 32),
nullptr);
681 EXPECT_EQ(dce_.lookup_decrypt_key(UINT16_MAX),
nullptr);
684 dce_.replace_update_recv_key(UINT16_MAX - 33, stats);
685 EXPECT_EQ(dce_.lookup_decrypt_key( UINT16_MAX - 33)->epoch, UINT16_MAX - 33);
686 EXPECT_EQ(dce_.lookup_decrypt_key(UINT16_MAX - 32),
nullptr);
687 EXPECT_EQ(dce_.lookup_decrypt_key(UINT16_MAX),
nullptr);