Skip to content

Commit 2debe3b

Browse files
committed
Allow for RFC8439 AD in cipher suite interface
1 parent cb50770 commit 2debe3b

File tree

5 files changed

+37
-14
lines changed

5 files changed

+37
-14
lines changed

src/bench/bip324_suite.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ static void BIP324_CIPHER_SUITE(benchmark::Bench& bench, size_t plaintext_len, b
3636

3737
bench.batch(plaintext_len).unit("byte").run([&] {
3838
// encrypt or decrypt the buffer with a static key
39-
const bool crypt_ok_1 = enc.Crypt(in, out, flags, true);
39+
const bool crypt_ok_1 = enc.Crypt({}, in, out, flags, true);
4040
assert(crypt_ok_1);
4141

4242
if (include_decryption) {
4343
// if we decrypt, we need to decrypt the length first
4444
std::array<std::byte, BIP324_LENGTH_FIELD_LEN> len_ciphertext;
4545
memcpy(len_ciphertext.data(), out.data(), BIP324_LENGTH_FIELD_LEN);
4646
(void)dec.DecryptLength(len_ciphertext);
47-
const bool crypt_ok_2 = dec.Crypt({out.data() + BIP324_LENGTH_FIELD_LEN, out.size() - BIP324_LENGTH_FIELD_LEN}, in, flags, false);
47+
const bool crypt_ok_2 = dec.Crypt({}, {out.data() + BIP324_LENGTH_FIELD_LEN, out.size() - BIP324_LENGTH_FIELD_LEN}, in, flags, false);
4848
assert(crypt_ok_2);
4949
}
5050
});

src/crypto/bip324_suite.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ void BIP324CipherSuite::CommitToKeys(const Span<const std::byte> data, bool comm
5454
set_nonce();
5555
}
5656

57-
bool BIP324CipherSuite::Crypt(const Span<const std::byte> input, Span<std::byte> output,
57+
bool BIP324CipherSuite::Crypt(const Span<const std::byte> aad,
58+
const Span<const std::byte> input,
59+
Span<std::byte> output,
5860
BIP324HeaderFlags& flags, bool encrypt)
5961
{
6062
// check buffer boundaries
@@ -84,13 +86,14 @@ bool BIP324CipherSuite::Crypt(const Span<const std::byte> input, Span<std::byte>
8486
fsc20.Crypt({reinterpret_cast<std::byte*>(&ciphertext_len), BIP324_LENGTH_FIELD_LEN},
8587
{write_pos, BIP324_LENGTH_FIELD_LEN});
8688
write_pos += BIP324_LENGTH_FIELD_LEN;
87-
RFC8439Encrypt({}, payload_key, nonce, input_vec, {write_pos, BIP324_HEADER_LEN + input.size() + RFC8439_TAGLEN});
89+
RFC8439Encrypt(aad, payload_key, nonce, input_vec, {write_pos, BIP324_HEADER_LEN + input.size() + RFC8439_TAGLEN});
90+
8891
} else {
8992
// we must use BIP324CipherSuite::DecryptLength before calling BIP324CipherSuite::Crypt
9093
// input is encrypted (header + payload) and the mac tag
9194
// decrypted header will be put in flags and output will be payload.
9295
std::vector<std::byte> decrypted_plaintext(input.size() - RFC8439_TAGLEN);
93-
auto authenticated = RFC8439Decrypt({}, payload_key, nonce, input, decrypted_plaintext);
96+
auto authenticated = RFC8439Decrypt(aad, payload_key, nonce, input, decrypted_plaintext);
9497
if (!authenticated) {
9598
return false;
9699
}

src/crypto/bip324_suite.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ class BIP324CipherSuite
6464
6565
Returns true upon success. Upon failure, the output should not be used.
6666
*/
67-
[[nodiscard]] bool Crypt(const Span<const std::byte> input, Span<std::byte> output, BIP324HeaderFlags& flags, bool encrypt);
67+
[[nodiscard]] bool Crypt(const Span<const std::byte> aad,
68+
const Span<const std::byte> input,
69+
Span<std::byte> output,
70+
BIP324HeaderFlags& flags, bool encrypt);
6871

6972
/** Decrypts the 3 byte length field ciphertext (the packet length) and decodes it into a uint32_t field
7073
The FSChaCha20 keystream will advance. As a result, DecryptLength() cannot be called multiple times to get the same result. The caller must cache the result for re-use.

src/test/crypto_tests.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ BOOST_AUTO_TEST_CASE(hkdf_hmac_sha256_l32_tests)
751751
"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d");
752752
}
753753

754-
static void TestBIP324CipherSuite(const std::string& hex_input, const std::string& hex_key_l, const std::string& hex_key_p, const std::string& hex_rekey_salt, const std::string& hex_expected_output_seq_0, const std::string& hex_expected_output_seq_999)
754+
static void TestBIP324CipherSuite(const std::string& hex_aad, const std::string& hex_input, const std::string& hex_key_l, const std::string& hex_key_p, const std::string& hex_rekey_salt, const std::string& hex_expected_output_seq_0, const std::string& hex_expected_output_seq_999)
755755
{
756756
auto key_l_vec = ParseHex(hex_key_l);
757757
BIP324Key key_l;
@@ -765,6 +765,8 @@ static void TestBIP324CipherSuite(const std::string& hex_input, const std::strin
765765
BIP324Key rekey_salt;
766766
memcpy(rekey_salt.data(), rekey_salt_vec.data(), BIP324_KEY_LEN);
767767

768+
auto aad = ParseHex(hex_aad);
769+
768770
const auto original_plaintext_bytes = ParseHex(hex_input);
769771
auto plaintext_buf = original_plaintext_bytes;
770772

@@ -781,7 +783,7 @@ static void TestBIP324CipherSuite(const std::string& hex_input, const std::strin
781783
// encrypt / decrypt the packet 1000 times
782784
for (size_t i = 0; i < 1000; ++i) {
783785
// encrypt
784-
auto res = suite_enc.Crypt(MakeByteSpan(plaintext_buf), MakeWritableByteSpan(ciphertext_buf), flags, true);
786+
auto res = suite_enc.Crypt(MakeByteSpan(aad), MakeByteSpan(plaintext_buf), MakeWritableByteSpan(ciphertext_buf), flags, true);
785787
BOOST_CHECK(res);
786788
// verify ciphertext & mac against the test vector
787789
if (i == 0) {
@@ -794,7 +796,7 @@ static void TestBIP324CipherSuite(const std::string& hex_input, const std::strin
794796
out_len = suite_dec.DecryptLength(length_ciphertext);
795797
BOOST_CHECK_EQUAL(out_len, BIP324_HEADER_LEN + plaintext_buf.size());
796798

797-
res = suite_dec.Crypt({reinterpret_cast<std::byte*>(ciphertext_buf.data()) + BIP324_LENGTH_FIELD_LEN, ciphertext_buf.size() - BIP324_LENGTH_FIELD_LEN}, MakeWritableByteSpan(plaintext_buf_dec), flags, false);
799+
res = suite_dec.Crypt(MakeByteSpan(aad), {reinterpret_cast<std::byte*>(ciphertext_buf.data()) + BIP324_LENGTH_FIELD_LEN, ciphertext_buf.size() - BIP324_LENGTH_FIELD_LEN}, MakeWritableByteSpan(plaintext_buf_dec), flags, false);
798800
BOOST_CHECK(res);
799801
BOOST_CHECK_EQUAL(flags, 0);
800802

@@ -812,33 +814,46 @@ BOOST_AUTO_TEST_CASE(bip324_cipher_suite_testvectors)
812814

813815
// encrypting an empty message should result in 20 bytes:
814816
// 3 bytes of encrypted length, 1 byte header and 16 bytes MAC
815-
TestBIP324CipherSuite(/* plaintext */ "",
817+
TestBIP324CipherSuite(/* aad */ "",
818+
/* plaintext */ "",
816819
/* k_l */ "0000000000000000000000000000000000000000000000000000000000000000",
817820
/* k_p */ "0000000000000000000000000000000000000000000000000000000000000000",
818821
/* rekey_salt */ "0000000000000000000000000000000000000000000000000000000000000000",
819822
/* ciphertext_and_mac_0 */ "77b8e09fbedcfd1809ff3c10adf8277fcc0581b8",
820823
/* ciphertext_and_mac_999 */ "8e6aedd9148bd3bafc2377f8e4f6559b4ec26ff4");
821824

822-
TestBIP324CipherSuite("0000000000000000000000000000000000000000000000000000000000000000",
825+
TestBIP324CipherSuite("",
826+
"0000000000000000000000000000000000000000000000000000000000000000",
823827
"0000000000000000000000000000000000000000000000000000000000000000",
824828
"0000000000000000000000000000000000000000000000000000000000000000",
825829
"0000000000000000000000000000000000000000000000000000000000000000",
826830
"57b8e09f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29e7e38bb44c94b6a43c525ffca66c79e9",
827831
"ae6aedd99d957e0f9719d248a1f25357573c4eb7fbf047911fd530bb2ec6cf6d921743a3d16ee9c81e352ba0a29a3c1c7dec8b6b");
828832

829-
TestBIP324CipherSuite("0100000000000000000000000000000000000000000000000000000000000000",
833+
TestBIP324CipherSuite("",
834+
"0100000000000000000000000000000000000000000000000000000000000000",
830835
"0000000000000000000000000000000000000000000000000000000000000000",
831836
"0000000000000000000000000000000000000000000000000000000000000000",
832837
"0000000000000000000000000000000000000000000000000000000000000000",
833838
"57b8e09f06e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed2929449b86c1e4e213676824f2c48e5336",
834839
"ae6aedd99c957e0f9719d248a1f25357573c4eb7fbf047911fd530bb2ec6cf6d921743a3fced1d140e9f3a4103e5c5e687cb2938");
835840

836-
TestBIP324CipherSuite("fc0000f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9",
841+
TestBIP324CipherSuite("",
842+
"fc0000f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9",
837843
"ff0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
838844
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
839845
"6f5ef19ed6f1a5e2db2b119494f21d8c2de638a4c6ec3b5b4d43f3196152ea10",
840846
"c641c1184442315c7340b89171039acb48f95287e66e56f7afa7cf00f95044d26fb69d46ac5c16a2d57a1cadc39160644717559e73480734410a3f543c5f231a7d7ed77af2a64681f6a7417283cef85504ac5de9fdea100e6c67ef7a1bfcd888a92a5f1ef2c9074b44b572aa748f29ff61a850ce40470004dff5cc1d926c5abe25ace47a12c5373094a26bab027e008154fb630aa062490b5421e96691a3f79557f7a79e3cfd9100796671ea241703ddf326f113adf1694bbd6e0ca032e16f936e7bfbf174e7ef4af5b53a6a9102e6fa41a8e589290f39a7bc7a6003088c612a43a36c2e9f2e740797ad3a2a1a80e0f67157fb9abc40487077368e94751a266a0b2dac24f0adabd5c6d7ba54316eee951da560",
841847
"7e3f8da87ddd62416fa860e3dcc8a999385425c07809de3b763e82545549d93f43a4cdb01b20e1049f68f31b13728fdf60fd8d65099ecc65d7fd90925733b7372057fa2174e487228fbb34e487a16342b721035f7f7ef26b962140aba9ba1a1a31e6bbacdfb406017f97449d3a6996b3266306bde62db2af8a3523ac5c65181b9b1818d1266a8d15ffb80675f84369411ab2bac744316180fbe08aa635dddc9dcaac7e249241665029b3ccae3b996840020dd46ce83e97a399568dcf1f58a8e29ee2535f5801ee006767218c01b31834e9ad0cf2cfd32321b16bd009233ea6a1896fbe2f6ebc2a6edfb8fcef6e4b90326b53b657f663f1f741f7f790abc2d97a1d57a3d3c2e024f783fe01dd00bad7254a1a21");
848+
849+
// Repeat test with non-empty aad - only mac tags (last 16 bytes) in the expected outputs change
850+
TestBIP324CipherSuite("c6d7bc3a5079ae98fec7094bdfb42aac61d3ba64af179d672c7c33fd4a139647",
851+
"fc0000f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9",
852+
"ff0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
853+
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
854+
"6f5ef19ed6f1a5e2db2b119494f21d8c2de638a4c6ec3b5b4d43f3196152ea10",
855+
"c641c1184442315c7340b89171039acb48f95287e66e56f7afa7cf00f95044d26fb69d46ac5c16a2d57a1cadc39160644717559e73480734410a3f543c5f231a7d7ed77af2a64681f6a7417283cef85504ac5de9fdea100e6c67ef7a1bfcd888a92a5f1ef2c9074b44b572aa748f29ff61a850ce40470004dff5cc1d926c5abe25ace47a12c5373094a26bab027e008154fb630aa062490b5421e96691a3f79557f7a79e3cfd9100796671ea241703ddf326f113adf1694bbd6e0ca032e16f936e7bfbf174e7ef4af5b53a6a9102e6fa41a8e589290f39a7bc7a6003088c612a43a36c2e9f2e740797ad3a2a1a80e0f67157fb9abc40487077368e94751a266a0b2dac4d382097b958da569f3b6fae3faaaaf2",
856+
"7e3f8da87ddd62416fa860e3dcc8a999385425c07809de3b763e82545549d93f43a4cdb01b20e1049f68f31b13728fdf60fd8d65099ecc65d7fd90925733b7372057fa2174e487228fbb34e487a16342b721035f7f7ef26b962140aba9ba1a1a31e6bbacdfb406017f97449d3a6996b3266306bde62db2af8a3523ac5c65181b9b1818d1266a8d15ffb80675f84369411ab2bac744316180fbe08aa635dddc9dcaac7e249241665029b3ccae3b996840020dd46ce83e97a399568dcf1f58a8e29ee2535f5801ee006767218c01b31834e9ad0cf2cfd32321b16bd009233ea6a1896fbe2f6ebc2a6edfb8fcef6e4b90326b53b657f663f1f741f7f790abc2d97a1d57a3e4a4b8689de67234c56961b9d0e71c35");
842857
}
843858

844859
BOOST_AUTO_TEST_CASE(countbits_tests)

src/test/fuzz/crypto_bip324_suite.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ FUZZ_TARGET(crypto_bip324_suite)
3737
std::vector<std::byte> out(BIP324_LENGTH_FIELD_LEN + BIP324_HEADER_LEN + buffer_size + RFC8439_TAGLEN, std::byte{0x00});
3838
bool is_encrypt = fdp.ConsumeBool();
3939
BIP324HeaderFlags flags{fdp.ConsumeIntegralInRange<uint8_t>(0, 255)};
40+
size_t aad_size = fdp.ConsumeIntegralInRange<size_t>(0, 255);
41+
auto aad = fdp.ConsumeBytes<std::byte>(aad_size);
4042
LIMITED_WHILE(fdp.ConsumeBool(), 10000)
4143
{
4244
CallOneOf(
@@ -50,7 +52,7 @@ FUZZ_TARGET(crypto_bip324_suite)
5052
flags = BIP324HeaderFlags{fdp.ConsumeIntegralInRange<uint8_t>(0, 255)};
5153
},
5254
[&] {
53-
(void)suite.Crypt(in, out, flags, is_encrypt);
55+
(void)suite.Crypt(aad, in, out, flags, is_encrypt);
5456
},
5557
[&] {
5658
std::array<std::byte, BIP324_LENGTH_FIELD_LEN> len_ciphertext;

0 commit comments

Comments
 (0)