Skip to content

Commit d809e89

Browse files
committed
Allow for RFC8439 AD in cipher suite interface
1 parent ee6112e commit d809e89

File tree

5 files changed

+36
-14
lines changed

5 files changed

+36
-14
lines changed

src/bench/bip324_suite.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ static void BIP324_CIPHER_SUITE(benchmark::Bench& bench, size_t contents_len, bo
3939

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

4545
if (include_decryption) {
4646
// if we decrypt, we need to decrypt the length first
4747
std::array<std::byte, BIP324_LENGTH_FIELD_LEN> encrypted_pkt_len;
4848
memcpy(encrypted_pkt_len.data(), out.data(), BIP324_LENGTH_FIELD_LEN);
4949
(void)dec.DecryptLength(encrypted_pkt_len);
50-
const bool crypt_ok_2 = dec.Crypt({out.data() + BIP324_LENGTH_FIELD_LEN, out.size() - BIP324_LENGTH_FIELD_LEN}, in, flags, false);
50+
const bool crypt_ok_2 = dec.Crypt({}, {out.data() + BIP324_LENGTH_FIELD_LEN, out.size() - BIP324_LENGTH_FIELD_LEN}, in, flags, false);
5151
assert(crypt_ok_2);
5252
}
5353
});

src/crypto/bip324_suite.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ void BIP324CipherSuite::CommitToKeys(const Span<const std::byte> data, bool comm
4949
set_nonce();
5050
}
5151

52-
bool BIP324CipherSuite::Crypt(const Span<const std::byte> input, Span<std::byte> output,
52+
bool BIP324CipherSuite::Crypt(const Span<const std::byte> aad,
53+
const Span<const std::byte> input,
54+
Span<std::byte> output,
5355
BIP324HeaderFlags& flags, bool encrypt)
5456
{
5557
// check buffer boundaries
@@ -78,13 +80,13 @@ bool BIP324CipherSuite::Crypt(const Span<const std::byte> input, Span<std::byte>
7880
fsc20.Crypt({reinterpret_cast<std::byte*>(&contents_len), BIP324_LENGTH_FIELD_LEN},
7981
{write_pos, BIP324_LENGTH_FIELD_LEN});
8082
write_pos += BIP324_LENGTH_FIELD_LEN;
81-
RFC8439Encrypt({}, key_P, nonce, header_and_contents, {write_pos, BIP324_HEADER_LEN + input.size() + RFC8439_EXPANSION});
83+
RFC8439Encrypt(aad, key_P, nonce, header_and_contents, {write_pos, BIP324_HEADER_LEN + input.size() + RFC8439_EXPANSION});
8284
} else {
8385
// we must use BIP324CipherSuite::DecryptLength before calling BIP324CipherSuite::Crypt
8486
// input is encrypted (header + contents) and the MAC tag i.e. the RFC8439 ciphertext blob
8587
// decrypted header will be put in flags and output will be plaintext contents.
8688
std::vector<std::byte> decrypted_header_and_contents(input.size() - RFC8439_EXPANSION);
87-
auto authenticated = RFC8439Decrypt({}, key_P, nonce, input, decrypted_header_and_contents);
89+
auto authenticated = RFC8439Decrypt(aad, key_P, nonce, input, decrypted_header_and_contents);
8890
if (!authenticated) {
8991
return false;
9092
}

src/crypto/bip324_suite.h

+4-1
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 encrypted length field (the packet header and contents 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

+22-7
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ BOOST_AUTO_TEST_CASE(hkdf_hmac_sha256_l32_tests)
833833
"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d");
834834
}
835835

836-
static void TestBIP324CipherSuite(const std::string& hex_contents, 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)
836+
static void TestBIP324CipherSuite(const std::string& hex_aad, const std::string& hex_contents, 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)
837837
{
838838
auto key_L_vec = ParseHex(hex_key_L);
839839
BIP324Key key_L;
@@ -847,6 +847,8 @@ static void TestBIP324CipherSuite(const std::string& hex_contents, const std::st
847847
std::array<std::byte, BIP324_REKEY_SALT_LEN> rekey_salt;
848848
memcpy(rekey_salt.data(), rekey_salt_vec.data(), BIP324_REKEY_SALT_LEN);
849849

850+
auto aad = ParseHex(hex_aad);
851+
850852
const auto original_contents_bytes = ParseHex(hex_contents);
851853
auto contents_buf = original_contents_bytes;
852854

@@ -863,7 +865,7 @@ static void TestBIP324CipherSuite(const std::string& hex_contents, const std::st
863865
// encrypt / decrypt the packet 1000 times
864866
for (size_t i = 0; i < 1000; ++i) {
865867
// encrypt
866-
auto res = suite_enc.Crypt(MakeByteSpan(contents_buf), MakeWritableByteSpan(encrypted_pkt), flags, true);
868+
auto res = suite_enc.Crypt(MakeByteSpan(aad), MakeByteSpan(contents_buf), MakeWritableByteSpan(encrypted_pkt), flags, true);
867869
BOOST_CHECK(res);
868870
// verify ciphertext & mac against the test vector
869871
if (i == 0) {
@@ -876,7 +878,7 @@ static void TestBIP324CipherSuite(const std::string& hex_contents, const std::st
876878
out_len = suite_dec.DecryptLength(encrypted_pkt_len);
877879
BOOST_CHECK_EQUAL(out_len, contents_buf.size());
878880

879-
res = suite_dec.Crypt({reinterpret_cast<std::byte*>(encrypted_pkt.data()) + BIP324_LENGTH_FIELD_LEN, encrypted_pkt.size() - BIP324_LENGTH_FIELD_LEN}, MakeWritableByteSpan(contents_buf_dec), flags, false);
881+
res = suite_dec.Crypt(MakeByteSpan(aad), {reinterpret_cast<std::byte*>(encrypted_pkt.data()) + BIP324_LENGTH_FIELD_LEN, encrypted_pkt.size() - BIP324_LENGTH_FIELD_LEN}, MakeWritableByteSpan(contents_buf_dec), flags, false);
880882
BOOST_CHECK(res);
881883
BOOST_CHECK_EQUAL(flags, BIP324_NONE);
882884

@@ -894,33 +896,46 @@ BOOST_AUTO_TEST_CASE(bip324_cipher_suite_testvectors)
894896

895897
// encrypting an empty message should result in 20 bytes:
896898
// 3 bytes of encrypted length, 1 byte header and 16 bytes MAC
897-
TestBIP324CipherSuite(/* plaintext */ "",
899+
TestBIP324CipherSuite(/* aad */ "",
900+
/* plaintext */ "",
898901
/* k_l */ "0000000000000000000000000000000000000000000000000000000000000000",
899902
/* k_p */ "0000000000000000000000000000000000000000000000000000000000000000",
900903
/* rekey_salt */ "0000000000000000000000000000000000000000000000",
901904
/* ciphertext_and_mac_0 */ "76b8e09fbedcfd1809ff3c10adf8277fcc0581b8",
902905
/* ciphertext_and_mac_999 */ "66712b97e33e72c0e908f5a7ce99279cb3cb6769");
903906

904-
TestBIP324CipherSuite("0000000000000000000000000000000000000000000000000000000000000000",
907+
TestBIP324CipherSuite("",
908+
"0000000000000000000000000000000000000000000000000000000000000000",
905909
"0000000000000000000000000000000000000000000000000000000000000000",
906910
"0000000000000000000000000000000000000000000000000000000000000000",
907911
"0000000000000000000000000000000000000000000000",
908912
"56b8e09f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29e7e38bb44c94b6a43c525ffca66c79e9",
909913
"46712b9741ee5bde86518fee0ce0778aa97cf58c1ee3c587ab3dce47de77b25f202b4807e074989c86c4bb8493e76cda937e0aad");
910914

911-
TestBIP324CipherSuite("0100000000000000000000000000000000000000000000000000000000000000",
915+
TestBIP324CipherSuite("",
916+
"0100000000000000000000000000000000000000000000000000000000000000",
912917
"0000000000000000000000000000000000000000000000000000000000000000",
913918
"0000000000000000000000000000000000000000000000000000000000000000",
914919
"0000000000000000000000000000000000000000000000",
915920
"56b8e09f06e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed2929449b86c1e4e213676824f2c48e5336",
916921
"46712b9740ee5bde86518fee0ce0778aa97cf58c1ee3c587ab3dce47de77b25f202b48079f2cc4249bd112ea04cccf99a211dfdb");
917922

918-
TestBIP324CipherSuite("fc0000f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9",
923+
TestBIP324CipherSuite("",
924+
"fc0000f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9",
919925
"ff0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
920926
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
921927
"6f5ef19ed6f1a5e2db2b119494f21d8c2de638a4c6ec3b",
922928
"3940c1184442315c7340b89171039acb48f95287e66e56f7afa7cf00f95044d26fb69d46ac5c16a2d57a1cadc39160644717559e73480734410a3f543c5f231a7d7ed77af2a64681f6a7417283cef85504ac5de9fdea100e6c67ef7a1bfcd888a92a5f1ef2c9074b44b572aa748f29ff61a850ce40470004dff5cc1d926c5abe25ace47a12c5373094a26bab027e008154fb630aa062490b5421e96691a3f79557f7a79e3cfd9100796671ea241703ddf326f113adf1694bbd6e0ca032e16f936e7bfbf174e7ef4af5b53a6a9102e6fa41a8e589290f39a7bc7a6003088c612a43a36c2e9f2e740797ad3a2a1a80e0f67157fb9abc40487077368e94751a266a0b2dac24f0adabd5c6d7ba54316eee951da560",
923929
"bcc270293211abbeac7a26af3f3d200f8ce44de3d3e86cdbf449dcf7fedb7b5a489629deaae0c87471b1331b2fce7aba3dfabf6f1867e1a534cececba0cdc9e6150e92cb145567401f08778eeb646b2a70165061423b30ca21e754d3e0a0db4de59dd74093b0fc0fc78a598d522571525ab172592620f770b3303c65ee4a35504e4991e8f1d8904c9679824140642c70a184b4449d1ffdf11b8bee4e831a5b3d986006f5119a0912bacb939886abcb279be2437ecbf1f56528ef397f6459f0fd895031c7a8a2a815a3e68199dc1a9b0c7fef3df72c470f9e8e5524049e7e712da407a6b8ab9a3c0a4ae40cc187952b1062e646b8aebc2808a381530791e46b7220a1af222022952872decc6ad5fad2a7b242a7");
930+
931+
// Repeat test with non-empty aad - only mac tags (last 16 bytes) in the expected outputs change
932+
TestBIP324CipherSuite("c6d7bc3a5079ae98fec7094bdfb42aac61d3ba64af179d672c7c33fd4a139647",
933+
"fc0000f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9",
934+
"ff0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
935+
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
936+
"6f5ef19ed6f1a5e2db2b119494f21d8c2de638a4c6ec3b5b4d43f3196152ea10",
937+
"3940c1184442315c7340b89171039acb48f95287e66e56f7afa7cf00f95044d26fb69d46ac5c16a2d57a1cadc39160644717559e73480734410a3f543c5f231a7d7ed77af2a64681f6a7417283cef85504ac5de9fdea100e6c67ef7a1bfcd888a92a5f1ef2c9074b44b572aa748f29ff61a850ce40470004dff5cc1d926c5abe25ace47a12c5373094a26bab027e008154fb630aa062490b5421e96691a3f79557f7a79e3cfd9100796671ea241703ddf326f113adf1694bbd6e0ca032e16f936e7bfbf174e7ef4af5b53a6a9102e6fa41a8e589290f39a7bc7a6003088c612a43a36c2e9f2e740797ad3a2a1a80e0f67157fb9abc40487077368e94751a266a0b2dac4d382097b958da569f3b6fae3faaaaf2",
938+
"bcc270293211abbeac7a26af3f3d200f8ce44de3d3e86cdbf449dcf7fedb7b5a489629deaae0c87471b1331b2fce7aba3dfabf6f1867e1a534cececba0cdc9e6150e92cb145567401f08778eeb646b2a70165061423b30ca21e754d3e0a0db4de59dd74093b0fc0fc78a598d522571525ab172592620f770b3303c65ee4a35504e4991e8f1d8904c9679824140642c70a184b4449d1ffdf11b8bee4e831a5b3d986006f5119a0912bacb939886abcb279be2437ecbf1f56528ef397f6459f0fd895031c7a8a2a815a3e68199dc1a9b0c7fef3df72c470f9e8e5524049e7e712da407a6b8ab9a3c0a4ae40cc187952b1062e646b8aebc2808a381530791e46b7220a1afd31f9f544f9ae60720005dca1ded9ac6");
924939
}
925940

926941
BOOST_AUTO_TEST_CASE(countbits_tests)

src/test/fuzz/crypto_bip324_suite.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ FUZZ_TARGET(crypto_bip324_suite)
3939
std::vector<std::byte> out(BIP324_LENGTH_FIELD_LEN + BIP324_HEADER_LEN + contents_size + RFC8439_EXPANSION, std::byte{0x00});
4040
bool is_encrypt = fdp.ConsumeBool();
4141
BIP324HeaderFlags flags{fdp.ConsumeIntegralInRange<uint8_t>(0, 255)};
42+
size_t aad_size = fdp.ConsumeIntegralInRange<size_t>(0, 255);
43+
auto aad = fdp.ConsumeBytes<std::byte>(aad_size);
4244
LIMITED_WHILE(fdp.ConsumeBool(), 10000)
4345
{
4446
CallOneOf(
@@ -52,7 +54,7 @@ FUZZ_TARGET(crypto_bip324_suite)
5254
flags = BIP324HeaderFlags{fdp.ConsumeIntegralInRange<uint8_t>(0, 255)};
5355
},
5456
[&] {
55-
(void)suite.Crypt(in, out, flags, is_encrypt);
57+
(void)suite.Crypt(aad, in, out, flags, is_encrypt);
5658
},
5759
[&] {
5860
std::array<std::byte, BIP324_LENGTH_FIELD_LEN> encrypted_pkt_len;

0 commit comments

Comments
 (0)