|
#!/usr/bin/env ruby
|
|
|
|
require 'openssl'
|
|
require 'tempfile'
|
|
require 'stringio'
|
|
|
|
plaintext_size = 199
|
|
|
|
write_cipher = OpenSSL::Cipher.new('AES-256-GCM')
|
|
write_cipher.encrypt
|
|
key = write_cipher.random_key
|
|
iv = write_cipher.random_iv
|
|
write_cipher.auth_data = ''
|
|
|
|
plaintext = Random.bytes(plaintext_size)
|
|
ciphertext = write_cipher.update(plaintext) + write_cipher.final
|
|
auth_tag = write_cipher.auth_tag
|
|
|
|
read_cipher = OpenSSL::Cipher.new('AES-256-GCM')
|
|
read_cipher.decrypt
|
|
read_cipher.key = key
|
|
read_cipher.iv = iv
|
|
read_cipher.auth_data = ''
|
|
read_cipher.auth_tag = auth_tag
|
|
|
|
read_pattern = [100, 99] # crashes
|
|
# read_pattern = [25, 25, 25, 25, 25, 25, 49] # works
|
|
# read_pattern = [25, 25, 25, 25, 25, 25, 25, 25] # crashes
|
|
# read_pattern = [25, 25, 25, 25, 25, 25, 25, 24] # crashes
|
|
# read_pattern = [25, 25, 25, 25, 25, 25, 25, 23, 1] # works
|
|
|
|
Tempfile.create do |tmp_file|
|
|
tmp_file.binmode
|
|
ciphertext_io = StringIO.new(ciphertext)
|
|
buffer = String.new
|
|
|
|
read_pattern.each do |size|
|
|
tmp_file.write(read_cipher.update(ciphertext_io.read(size), buffer))
|
|
end
|
|
|
|
tmp_file.write(read_cipher.final)
|
|
|
|
tmp_file.rewind
|
|
raise 'round-trip failed' if tmp_file.read != plaintext
|
|
end
|