summaryrefslogtreecommitdiff
path: root/test/openssl/test_cipher.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/openssl/test_cipher.rb')
-rw-r--r--test/openssl/test_cipher.rb103
1 files changed, 68 insertions, 35 deletions
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
index cd0b3dcb44..6a405da0a9 100644
--- a/test/openssl/test_cipher.rb
+++ b/test/openssl/test_cipher.rb
@@ -32,28 +32,28 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
salt = "\x01" * 8
num = 2048
pt = "data to be encrypted"
- cipher = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
- cipher.pkcs5_keyivgen(pass, salt, num, "MD5")
+ cipher = OpenSSL::Cipher.new("AES-256-CBC").encrypt
+ cipher.pkcs5_keyivgen(pass, salt, num, "SHA256")
s1 = cipher.update(pt) << cipher.final
- d1 = num.times.inject(pass + salt) {|out, _| OpenSSL::Digest.digest('MD5', out) }
- d2 = num.times.inject(d1 + pass + salt) {|out, _| OpenSSL::Digest.digest('MD5', out) }
- key = (d1 + d2)[0, 24]
- iv = (d1 + d2)[24, 8]
- cipher = new_encryptor("DES-EDE3-CBC", key: key, iv: iv)
+ d1 = num.times.inject(pass + salt) {|out, _| OpenSSL::Digest.digest('SHA256', out) }
+ d2 = num.times.inject(d1 + pass + salt) {|out, _| OpenSSL::Digest.digest('SHA256', out) }
+ key = (d1 + d2)[0, 32]
+ iv = (d1 + d2)[32, 16]
+ cipher = new_encryptor("AES-256-CBC", key: key, iv: iv)
s2 = cipher.update(pt) << cipher.final
assert_equal s1, s2
- cipher2 = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
- assert_raise(ArgumentError) { cipher2.pkcs5_keyivgen(pass, salt, -1, "MD5") }
+ cipher2 = OpenSSL::Cipher.new("AES-256-CBC").encrypt
+ assert_raise(ArgumentError) { cipher2.pkcs5_keyivgen(pass, salt, -1, "SHA256") }
end
def test_info
- cipher = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
- assert_equal "DES-EDE3-CBC", cipher.name
- assert_equal 24, cipher.key_len
- assert_equal 8, cipher.iv_len
+ cipher = OpenSSL::Cipher.new("AES-256-CBC").encrypt
+ assert_equal "AES-256-CBC", cipher.name
+ assert_equal 32, cipher.key_len
+ assert_equal 16, cipher.iv_len
end
def test_dup
@@ -80,13 +80,13 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
end
def test_key_iv_set
- cipher = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
- assert_raise(ArgumentError) { cipher.key = "\x01" * 23 }
- assert_nothing_raised { cipher.key = "\x01" * 24 }
- assert_raise(ArgumentError) { cipher.key = "\x01" * 25 }
- assert_raise(ArgumentError) { cipher.iv = "\x01" * 7 }
- assert_nothing_raised { cipher.iv = "\x01" * 8 }
- assert_raise(ArgumentError) { cipher.iv = "\x01" * 9 }
+ cipher = OpenSSL::Cipher.new("AES-256-CBC").encrypt
+ assert_raise(ArgumentError) { cipher.key = "\x01" * 31 }
+ assert_nothing_raised { cipher.key = "\x01" * 32 }
+ assert_raise(ArgumentError) { cipher.key = "\x01" * 33 }
+ assert_raise(ArgumentError) { cipher.iv = "\x01" * 15 }
+ assert_nothing_raised { cipher.iv = "\x01" * 16 }
+ assert_raise(ArgumentError) { cipher.iv = "\x01" * 17 }
end
def test_random_key_iv
@@ -109,9 +109,12 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
end
def test_initialize
- cipher = OpenSSL::Cipher.new("DES-EDE3-CBC")
- assert_raise(RuntimeError) { cipher.__send__(:initialize, "DES-EDE3-CBC") }
+ cipher = OpenSSL::Cipher.new("AES-256-CBC")
+ assert_raise(RuntimeError) { cipher.__send__(:initialize, "AES-256-CBC") }
assert_raise(RuntimeError) { OpenSSL::Cipher.allocate.final }
+ assert_raise(OpenSSL::Cipher::CipherError) {
+ OpenSSL::Cipher.new("no such algorithm")
+ }
end
def test_ctr_if_exists
@@ -131,13 +134,14 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
def test_update_with_buffer
cipher = OpenSSL::Cipher.new("aes-128-ecb").encrypt
cipher.random_key
- expected = cipher.update("data") << cipher.final
- assert_equal 16, expected.bytesize
+ expected = cipher.update("data" * 10) << cipher.final
+ assert_equal 48, expected.bytesize
# Buffer is supplied
cipher.reset
buf = String.new
- assert_same buf, cipher.update("data", buf)
+ assert_same buf, cipher.update("data" * 10, buf)
+ assert_equal 32, buf.bytesize
assert_equal expected, buf + cipher.final
# Buffer is frozen
@@ -146,9 +150,9 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
# Buffer is a shared string [ruby-core:120141] [Bug #20937]
cipher.reset
- buf = "x" * 1024
- shared = buf[-("data".bytesize + 32)..-1]
- assert_same shared, cipher.update("data", shared)
+ buf = "x".b * 1024
+ shared = buf[-("data".bytesize * 10 + 32)..-1]
+ assert_same shared, cipher.update("data" * 10, shared)
assert_equal expected, shared + cipher.final
end
@@ -165,12 +169,12 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
%w(ecb cbc cfb ofb).each{|mode|
c1 = OpenSSL::Cipher.new("aes-256-#{mode}")
c1.encrypt
- c1.pkcs5_keyivgen("passwd")
+ c1.pkcs5_keyivgen("passwd", "12345678", 10000, "SHA256")
ct = c1.update(pt) + c1.final
c2 = OpenSSL::Cipher.new("aes-256-#{mode}")
c2.decrypt
- c2.pkcs5_keyivgen("passwd")
+ c2.pkcs5_keyivgen("passwd", "12345678", 10000, "SHA256")
assert_equal(pt, c2.update(ct) + c2.final)
}
end
@@ -182,6 +186,10 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
end
end
+ def test_auth_tag_error_inheritance
+ assert_equal OpenSSL::Cipher::CipherError, OpenSSL::Cipher::AuthTagError.superclass
+ end
+
def test_authenticated
cipher = OpenSSL::Cipher.new('aes-128-gcm')
assert_predicate(cipher, :authenticated?)
@@ -212,7 +220,8 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
cipher = new_decryptor("aes-128-ccm", **kwargs, ccm_data_len: ct.length, auth_tag: tag[0, 8], auth_data: aad)
assert_equal pt, cipher.update(ct) << cipher.final
- # wrong tag is rejected
+ # wrong tag is rejected - in CCM, authentication happens during update, but
+ # we consider this a general CipherError since update failures can have various causes
tag2 = tag.dup
tag2.setbyte(-1, (tag2.getbyte(-1) + 1) & 0xff)
cipher = new_decryptor("aes-128-ccm", **kwargs, ccm_data_len: ct.length, auth_tag: tag2, auth_data: aad)
@@ -265,19 +274,19 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
tag2.setbyte(-1, (tag2.getbyte(-1) + 1) & 0xff)
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_tag: tag2, auth_data: aad)
cipher.update(ct)
- assert_raise(OpenSSL::Cipher::CipherError) { cipher.final }
+ assert_raise(OpenSSL::Cipher::AuthTagError) { cipher.final }
# wrong aad is rejected
aad2 = aad[0..-2] << aad[-1].succ
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_tag: tag, auth_data: aad2)
cipher.update(ct)
- assert_raise(OpenSSL::Cipher::CipherError) { cipher.final }
+ assert_raise(OpenSSL::Cipher::AuthTagError) { cipher.final }
# wrong ciphertext is rejected
ct2 = ct[0..-2] << ct[-1].succ
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_tag: tag, auth_data: aad)
cipher.update(ct2)
- assert_raise(OpenSSL::Cipher::CipherError) { cipher.final }
+ assert_raise(OpenSSL::Cipher::AuthTagError) { cipher.final }
end
def test_aes_gcm_variable_iv_len
@@ -304,6 +313,9 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
end
def test_aes_ocb_tag_len
+ # AES-128-OCB is not FIPS-approved.
+ omit_on_fips
+
# RFC 7253 Appendix A; the second sample
key = ["000102030405060708090A0B0C0D0E0F"].pack("H*")
iv = ["BBAA99887766554433221101"].pack("H*")
@@ -337,6 +349,27 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
end if has_cipher?("aes-128-ocb")
+ def test_aes_gcm_siv
+ # AES-128-GCM-SIV is not FIPS-approved.
+ omit_on_fips
+
+ # RFC 8452 Appendix C.1., 8th example
+ key = ["01000000000000000000000000000000"].pack("H*")
+ iv = ["030000000000000000000000"].pack("H*")
+ aad = ["01"].pack("H*")
+ pt = ["0200000000000000"].pack("H*")
+ ct = ["1e6daba35669f4273b0a1a2560969cdf790d99759abd1508"].pack("H*")
+ tag = ["3b0a1a2560969cdf790d99759abd1508"].pack("H*")
+ ct_without_tag = ct.byteslice(0, ct.bytesize - tag.bytesize)
+
+ cipher = new_encryptor("aes-128-gcm-siv", key: key, iv: iv, auth_data: aad)
+ assert_equal ct_without_tag, cipher.update(pt) << cipher.final
+ assert_equal tag, cipher.auth_tag
+ cipher = new_decryptor("aes-128-gcm-siv", key: key, iv: iv, auth_tag: tag,
+ auth_data: aad)
+ assert_equal pt, cipher.update(ct_without_tag) << cipher.final
+ end if openssl?(3, 2, 0)
+
def test_aes_gcm_key_iv_order_issue
pt = "[ruby/openssl#49]"
cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
@@ -363,7 +396,7 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
begin
cipher = OpenSSL::Cipher.new("id-aes192-wrap-pad").encrypt
- rescue OpenSSL::Cipher::CipherError, RuntimeError
+ rescue OpenSSL::Cipher::CipherError
omit "id-aes192-wrap-pad is not supported: #$!"
end
cipher.key = kek