From 58718b3b0a1570c0bcb69723907966bccf2b8922 Mon Sep 17 00:00:00 2001 From: hashlag Date: Sun, 20 Sep 2026 20:40:55 +0300 Subject: [PATCH] Fix a logical bug where Arc4Crypt was left in invalid state after a failed Rekey() call. --- Chaos/Cipher/Stream/Arc4/Arc4Crypt.hpp | 1 + .../Cipher/Stream/Arc4/Arc4CryptTests.cpp | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/Chaos/Cipher/Stream/Arc4/Arc4Crypt.hpp b/Chaos/Cipher/Stream/Arc4/Arc4Crypt.hpp index 7395d1e..b35111c 100644 --- a/Chaos/Cipher/Stream/Arc4/Arc4Crypt.hpp +++ b/Chaos/Cipher/Stream/Arc4/Arc4Crypt.hpp @@ -59,6 +59,7 @@ private: template void RekeyImpl(InputIt keyBegin, InputIt keyEnd) { + IsInitialized_ = false; Gen_.Rekey(keyBegin, keyEnd); IsInitialized_ = true; } diff --git a/ChaosTests/Cipher/Stream/Arc4/Arc4CryptTests.cpp b/ChaosTests/Cipher/Stream/Arc4/Arc4CryptTests.cpp index 763f293..a1f2395 100644 --- a/ChaosTests/Cipher/Stream/Arc4/Arc4CryptTests.cpp +++ b/ChaosTests/Cipher/Stream/Arc4/Arc4CryptTests.cpp @@ -117,6 +117,61 @@ TEST(Arc4CryptTests, RekeyTest) } } +TEST(Arc4CryptTests, RekeyFailSafetyTest) +{ + const std::vector key = StrToU8Vec("Secret"); + const std::vector data = StrToU8Vec("Attack at dawn"); + + Arc4Crypt arc4(key.begin(), key.end()); + + { + std::vector ciphertext; + ciphertext.resize(data.size()); + + arc4.Encrypt(ciphertext.begin(), data.begin(), data.size()); + + ASSERT_EQ(std::vector({ 0x45, 0xA0, 0x1F, 0x64, 0x5F, 0xC3, 0x5B, + 0x38, 0x35, 0x52, 0x54, 0x4B, 0x9B, 0xF5 }), + ciphertext); + } + + { + std::array in = {}; + std::array out = {}; + + uint8_t smallKey[] = { 0x01, 0x02, 0x03 }; + ASSERT_THROW_EX(arc4.Rekey(smallKey, smallKey + std::size(smallKey)), + Chaos::Service::ChaosException, + { + ASSERT_EQ("Arc4Gen: key is too small", ex.GetMessage()); + }); + + ASSERT_THROW_EX(arc4.Encrypt(out.begin(), in.begin(), in.size()), + Chaos::Service::ChaosException, + { + ASSERT_EQ("Arc4Crypt: not initialized", ex.GetMessage()); + }); + + ASSERT_THROW_EX(arc4.Decrypt(out.begin(), in.begin(), in.size()), + Chaos::Service::ChaosException, + { + ASSERT_EQ("Arc4Crypt: not initialized", ex.GetMessage()); + }); + } + + { + std::vector ciphertext; + ciphertext.resize(data.size()); + + arc4.Rekey(key.begin(), key.end()); + arc4.Encrypt(ciphertext.begin(), data.begin(), data.size()); + + ASSERT_EQ(std::vector({ 0x45, 0xA0, 0x1F, 0x64, 0x5F, 0xC3, 0x5B, + 0x38, 0x35, 0x52, 0x54, 0x4B, 0x9B, 0xF5 }), + ciphertext); + } +} + TEST(Arc4CryptTests, EncryptOutIteratorUsageTest) { const std::vector data = StrToU8Vec("The quick brown fox jumps over the lazy dog.");