diff --git a/src/lib/server/CClientProxy1_4.cpp b/src/lib/server/CClientProxy1_4.cpp index 81d86208..73473356 100644 --- a/src/lib/server/CClientProxy1_4.cpp +++ b/src/lib/server/CClientProxy1_4.cpp @@ -103,6 +103,10 @@ CClientProxy1_4::cryptoIv() LOG((CLOG_DEBUG2 "send crypto iv change to \"%s\"", getName().c_str())); CProtocolUtil::writef(getStream(), kMsgDCryptoIv, &data); + + // change IV only after we've sent the current IV, otherwise + // the client won't be able to decrypt the new IV. + cryptoStream->setIv(iv); } bool diff --git a/src/lib/synergy/CCryptoStream.cpp b/src/lib/synergy/CCryptoStream.cpp index fe140242..e7824247 100644 --- a/src/lib/synergy/CCryptoStream.cpp +++ b/src/lib/synergy/CCryptoStream.cpp @@ -124,7 +124,6 @@ void CCryptoStream::newIv(byte* out) { m_autoSeedRandomPool.GenerateBlock(out, CRYPTO_IV_SIZE); - setIv(out); } void diff --git a/src/test/unittests/synergy/CCryptoStreamTests.cpp b/src/test/unittests/synergy/CCryptoStreamTests.cpp index 9ea027bd..83b98161 100644 --- a/src/test/unittests/synergy/CCryptoStreamTests.cpp +++ b/src/test/unittests/synergy/CCryptoStreamTests.cpp @@ -56,6 +56,9 @@ UInt8 g_readWriteIvChangeTrigger_buffer[4 + 4 + 16]; // abcd, DCIV, 16-byte IV void readWriteIvChangeTrigger_mockWrite(const void* in, UInt32 n); UInt8 readWriteIvChangeTrigger_mockRead(void* out, UInt32 n); +UInt8 g_newIvDoesNotChangeIv_buffer[1]; +void newIvDoesNotChangeIv_mockWrite(const void* in, UInt32 n); + TEST(CCryptoTests, write) { const UInt32 size = 4; @@ -248,6 +251,25 @@ TEST(CCryptoTests, createKey) EXPECT_EQ(hash3[31], 233); } +TEST(CCryptoTests, newIvDoesNotChangeIv) +{ + NiceMock eventQueue; + NiceMock innerStream; + CCryptoOptions options("ctr", "mock"); + + ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(newIvDoesNotChangeIv_mockWrite)); + + CCryptoStream cs1(&eventQueue, &innerStream, options, false); + cs1.write("a", 1); + EXPECT_EQ(175, g_newIvDoesNotChangeIv_buffer[0]); + + byte iv[CRYPTO_IV_SIZE]; + cs1.newIv(iv); + + cs1.write("a", 1); + EXPECT_EQ(92, g_newIvDoesNotChangeIv_buffer[0]); +} + void write_mockWrite(const void* in, UInt32 n) { @@ -318,3 +340,9 @@ readWriteIvChangeTrigger_mockRead(void* out, UInt32 n) g_readWriteIvChangeTrigger_readBufferIndex += n; return n; } + +void +newIvDoesNotChangeIv_mockWrite(const void* in, UInt32 n) +{ + memcpy(g_newIvDoesNotChangeIv_buffer, in, 1); +}