aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_cipher.rb
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-07-02 20:37:20 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-07-09 02:46:37 +0900
commit01e18485d81e562688be739f902c78965fc1f0be (patch)
treec1baeb44beaca2a540efa47c652cbe039b9aadd0 /test/test_cipher.rb
parent1b8bcdb1dc06626a285859570a1e67037df47d8e (diff)
downloadruby-openssl-01e18485d81e562688be739f902c78965fc1f0be.tar.gz
cipher: allow setting IV length when using AEAD cipherstopic/cipher-iv-len
Add OpenSSL::Cipher#iv_len=. For interoperability with other applications, it is sometimes required. Normally 'IV' is fixed-length, but in OpenSSL, some ciphers such as aes-128-gcm make use of it as 'nonce', which is variable-length. Changing the IV length in Cipher#iv= is also an option but I decided not to choose it. Because in Ruby <= 2.3 Cipher#iv= truncates the input when the length is longer than the current IV length, changing the behavior might cause unexpected encryption result. [Bug #8667] [Bug #10420] [GH ruby/ruby#569]
Diffstat (limited to 'test/test_cipher.rb')
-rw-r--r--test/test_cipher.rb40
1 files changed, 40 insertions, 0 deletions
diff --git a/test/test_cipher.rb b/test/test_cipher.rb
index ec14f467..dffc0d7b 100644
--- a/test/test_cipher.rb
+++ b/test/test_cipher.rb
@@ -247,6 +247,46 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
end
end
+ def test_aes_gcm_variable_iv_len
+ pt = "You should all use Authenticated Encryption!"
+ cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
+ cipher.key = "x" * 16
+ assert_equal(12, cipher.iv_len)
+ cipher.iv = "a" * 12
+ ct1 = cipher.update(pt) << cipher.final
+ tag1 = cipher.auth_tag
+
+ cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
+ cipher.key = "x" * 16
+ cipher.iv_len = 10
+ assert_equal(10, cipher.iv_len)
+ cipher.iv = "a" * 10
+ ct2 = cipher.update(pt) << cipher.final
+ tag2 = cipher.auth_tag
+
+ assert_not_equal ct1, ct2
+ assert_not_equal tag1, tag2
+
+ decipher = OpenSSL::Cipher.new("aes-128-gcm").decrypt
+ decipher.auth_tag = tag1
+ decipher.key = "x" * 16
+ decipher.iv_len = 12
+ decipher.iv = "a" * 12
+ assert_equal(pt, decipher.update(ct1) << decipher.final)
+
+ decipher.reset
+ decipher.auth_tag = tag2
+ assert_raise(OpenSSL::Cipher::CipherError) {
+ decipher.update(ct2) << decipher.final
+ }
+
+ decipher.reset
+ decipher.auth_tag = tag2
+ decipher.iv_len = 10
+ decipher.iv = "a" * 10
+ assert_equal(pt, decipher.update(ct2) << decipher.final)
+ end
+
end
private