diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-07-02 20:37:20 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-07-09 02:46:37 +0900 |
commit | 01e18485d81e562688be739f902c78965fc1f0be (patch) | |
tree | c1baeb44beaca2a540efa47c652cbe039b9aadd0 /test/test_cipher.rb | |
parent | 1b8bcdb1dc06626a285859570a1e67037df47d8e (diff) | |
download | ruby-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.rb | 40 |
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 |