diff --git a/lib/net/ssh/transport/ctr.rb b/lib/net/ssh/transport/ctr.rb index bc9480d9e..6c7c86c65 100644 --- a/lib/net/ssh/transport/ctr.rb +++ b/lib/net/ssh/transport/ctr.rb @@ -3,6 +3,11 @@ module Net::SSH::Transport #:nodoc: class OpenSSLAESCTR < SimpleDelegator + def initialize(original) + super + @was_reset = false + end + def block_size 16 end @@ -10,6 +15,14 @@ def block_size def self.block_size 16 end + + def reset + @was_reset = true + end + + def iv=(iv_s) + super unless @was_reset + end end #:nodoc: diff --git a/test/transport/test_cipher_factory.rb b/test/transport/test_cipher_factory.rb index bbc6525e0..5b9ba7dbc 100644 --- a/test/transport/test_cipher_factory.rb +++ b/test/transport/test_cipher_factory.rb @@ -56,11 +56,11 @@ def test_lengths_for_arcfour def test_lengths_for_arcfour128 assert_equal [16,8], factory.get_lengths("arcfour128") end - + def test_lengths_for_arcfour256 assert_equal [32,8], factory.get_lengths("arcfour256") end - + def test_lengths_for_arcfour512 assert_equal [64,8], factory.get_lengths("arcfour512") end @@ -180,33 +180,33 @@ def test_arcfour_for_encryption def test_arcfour_for_decryption assert_equal TEXT, decrypt("arcfour", ARCFOUR) end - + ARCFOUR128 = "\n\x90\xED*\xD4\xBE\xCBg5\xA5\a\xEC]\x97\xB7L\x06)6\x12FL\x90@\xF4Sqxqh\r\x11\x1Aq \xC8\xE6v\xC6\x12\xD9]\xD6\xC4<\x1DBd\xA9\x02\x9C\xEB\x89#\x955\xD6\x0F\xD0\x03\xF9\xC6\xD7\xB0@\e\\\xAB\xC0\xA9\xFB\x91\#{w\xADL\xF6'(\xCC\x14\xA2A\x16\xC1\x9C'\xD1\xBA'i\x88\x80\xF1\xA7E\x82\xA8\xC7@\xBA\a\xEA" def test_aes128_ctr_for_encryption assert_equal AES128_CTR, encrypt("aes128-ctr") end + def test_aes128_ctr_for_encryption2 + assert_equal [AES128_CTR, AES128_CTR2], encrypt2("aes128-ctr") + end + + def test_aes128_ctr_for_decryption2 + assert_equal [TEXT, TEXT2], decrypt2("aes128-ctr", [AES128_CTR, AES128_CTR2]) + end + def test_aes128_ctr_for_decryption assert_equal TEXT, decrypt("aes128-ctr", AES128_CTR) end @@ -272,11 +281,16 @@ def test_aes192_ctr_for_decryption end AES256_CTR = "2\xB8\xE6\xC9\x95\xB4\x05\xD2\xC7+\x7F\x88\xEB\xD4\xA0\b\"\xBF\x9E\x85t\x19,\e\x90\x11\x04b\xC7\xEE$\xDE\xE6\xC5@G\xFEm\xE1u\x9B\au\xAF\xB5\xB8\x857\x87\x139u\xAC\x1A\xAB\fh\x8FiW~\xB8:\xA4\xA0#~\xC4\x89\xBA5#:\xFC\xC8\xE3\x9B\xF0A2\x87\x980\xD1\xE3\xBC'\xBE\x1E\n\x1A*B\x06\xF3\xCC" + AES256_CTR2 = "\x13\xBF}\x93\xC3\xFCkw[\\\x8A\xDA\x9F\x85e3AH!\x19\xD9S(+x]B\x1A\x85):\x1Ce\xB1\xD1\x9F^\x8D\\\xFA\xFE\xC6\x9FDkm=?>.\x93\xA6O\x80\xB5o\xBE\xB5\\82\xEEWi\xFC<\xA7\xB6g\xBD\xF1\xA6\xAA\xE7\xD3_&N\xC9[K8\xE61L\xD1\xC0\xC8\x02\b\xE7\xF1!\xA5\x04\xCA" def test_aes256_ctr_for_encryption assert_equal AES256_CTR, encrypt("aes256-ctr") end + def test_aes256_ctr_for_encryption2 + assert_equal [AES256_CTR,AES256_CTR2], encrypt2("aes256-ctr") + end + def test_aes256_ctr_for_decryption assert_equal TEXT, decrypt("aes256-ctr", AES256_CTR) end @@ -289,10 +303,11 @@ def test_none_for_encryption def test_none_for_decryption assert_equal TEXT, decrypt("none", TEXT) end - + private TEXT = "But soft! What light through yonder window breaks? It is the east, and Juliet is the sun!" + TEXT2 = "2But soft! What light through yonder window breaks? It is the east, and Juliet is the sun!" OPTIONS = { iv: "ABC", key: "abc", @@ -312,12 +327,43 @@ def encrypt(type) result << cipher.final end + def encrypt2(type) + cipher = factory.get(type, OPTIONS.merge(encrypt: true)) + padding = TEXT.length % cipher.block_size + result = cipher.update(TEXT.dup) + result << cipher.update(" " * (cipher.block_size - padding)) if padding > 0 + result << cipher.final + + cipher.reset + + cipher.iv = "0123456789123456" + padding = TEXT2.length % cipher.block_size + result2 = cipher.update(TEXT2.dup) + result2 << cipher.update(" " * (cipher.block_size - padding)) if padding > 0 + result2 << cipher.final + [result, result2] + end + def decrypt(type, data) cipher = factory.get(type, OPTIONS.merge(decrypt: true)) result = cipher.update(data.dup) result << cipher.final result.strip end + + def decrypt2(type, datas) + cipher = factory.get(type, OPTIONS.merge(decrypt: true)) + result = cipher.update(datas[0].dup) + result << cipher.final + first = result.strip + + cipher.reset + + result = cipher.update(datas[1].dup) + result << cipher.final + second = result.strip + [first, second] + end end end