From 7aa557150dcb03b2240b58bc3c874f0253ce8897 Mon Sep 17 00:00:00 2001 From: Vít Ondruch Date: Jul 27 2017 07:49:22 +0000 Subject: Fix IV Reuse in GCM Mode (rhbz#1381527). --- diff --git a/ruby-2.3.4-remove-the-encryption-key-initialization.patch b/ruby-2.3.4-remove-the-encryption-key-initialization.patch new file mode 100644 index 0000000..d375f5c --- /dev/null +++ b/ruby-2.3.4-remove-the-encryption-key-initialization.patch @@ -0,0 +1,170 @@ +From 739782e37a6662fea379e7ef3ec89e851b04b46c Mon Sep 17 00:00:00 2001 +From: usa +Date: Wed, 5 Jul 2017 07:06:45 +0000 +Subject: [PATCH] * ext/openssl/ossl_cipher.c: remove the encryption key + initialization from Cipher#initialize. This is effectively a revert of + r32723 ("Avoid possible SEGV from AES encryption/decryption", 2011-07-28). + the patch is derived from + https://github.com/ruby/openssl/commit/8108e0a6db133f3375608303fdd2083eb5115062, + written by Kazuki Yamaguchi. [Backport #8221] + +git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@59267 b2dd03c8-39d4-4d8f-98ff-823fe69b080e +--- + ChangeLog | 9 +++++++++ + ext/openssl/ossl_cipher.c | 23 ++++++++++++++--------- + test/openssl/test_cipher.rb | 29 +++++++++++++++++++++++------ + version.h | 6 +++--- + 3 files changed, 46 insertions(+), 15 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 33b9dbe79fef..ad89c9c4bd52 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,12 @@ ++Wed Jul 5 15:55:35 2017 NAKAMURA Usaku ++ ++ * ext/openssl/ossl_cipher.c: remove the encryption key initialization ++ from Cipher#initialize. This is effectively a revert of r32723 ++ ("Avoid possible SEGV from AES encryption/decryption", 2011-07-28). ++ the patch is derived from https://github.com/ruby/openssl/commit/8108e0a6db133f3375608303fdd2083eb5115062, ++ written by Kazuki Yamaguchi. ++ [Backport #8221] ++ + Mon Nov 21 16:55:15 2016 boshan + + * lib/tempfile.rb (Tempfile#initialize): [DOC] the first parameter +diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c +index 09b021d9873a..24caba6e3721 100644 +--- a/ext/openssl/ossl_cipher.c ++++ b/ext/openssl/ossl_cipher.c +@@ -34,6 +34,7 @@ + */ + VALUE cCipher; + VALUE eCipherError; ++static ID id_key_set; + + static VALUE ossl_cipher_alloc(VALUE klass); + static void ossl_cipher_free(void *ptr); +@@ -114,7 +115,6 @@ ossl_cipher_initialize(VALUE self, VALUE str) + EVP_CIPHER_CTX *ctx; + const EVP_CIPHER *cipher; + char *name; +- unsigned char key[EVP_MAX_KEY_LENGTH]; + + name = StringValuePtr(str); + GetCipherInit(self, ctx); +@@ -126,14 +126,7 @@ ossl_cipher_initialize(VALUE self, VALUE str) + if (!(cipher = EVP_get_cipherbyname(name))) { + ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name); + } +- /* +- * The EVP which has EVP_CIPH_RAND_KEY flag (such as DES3) allows +- * uninitialized key, but other EVPs (such as AES) does not allow it. +- * Calling EVP_CipherUpdate() without initializing key causes SEGV so we +- * set the data filled with "\0" as the key by default. +- */ +- memset(key, 0, EVP_MAX_KEY_LENGTH); +- if (EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, -1) != 1) ++ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) + ossl_raise(eCipherError, NULL); + + return self; +@@ -252,6 +245,9 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) + ossl_raise(eCipherError, NULL); + } + ++ if (p_key) ++ rb_ivar_set(self, id_key_set, Qtrue); ++ + return self; + } + +@@ -338,6 +334,8 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) + OPENSSL_cleanse(key, sizeof key); + OPENSSL_cleanse(iv, sizeof iv); + ++ rb_ivar_set(self, id_key_set, Qtrue); ++ + return Qnil; + } + +@@ -391,6 +389,9 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) + + rb_scan_args(argc, argv, "11", &data, &str); + ++ if (!RTEST(rb_attr_get(self, id_key_set))) ++ ossl_raise(eCipherError, "key not set"); ++ + StringValue(data); + in = (unsigned char *)RSTRING_PTR(data); + if ((in_len = RSTRING_LEN(data)) == 0) +@@ -490,6 +491,8 @@ ossl_cipher_set_key(VALUE self, VALUE key) + if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1) + ossl_raise(eCipherError, NULL); + ++ rb_ivar_set(self, id_key_set, Qtrue); ++ + return key; + } + +@@ -1008,4 +1011,6 @@ Init_ossl_cipher(void) + rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0); + rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0); + rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1); ++ ++ id_key_set = rb_intern_const("key_set"); + } +diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb +index 89c176f4de41..95058b5f196b 100644 +--- a/test/openssl/test_cipher.rb ++++ b/test/openssl/test_cipher.rb +@@ -81,6 +81,7 @@ def test_reset + + def test_empty_data + @c1.encrypt ++ @c1.random_key + assert_raise(ArgumentError){ @c1.update("") } + end + +@@ -129,12 +130,10 @@ def test_AES + } + end + +- def test_AES_crush +- 500.times do +- assert_nothing_raised("[Bug #2768]") do +- # it caused OpenSSL SEGV by uninitialized key +- OpenSSL::Cipher::AES128.new("ECB").update "." * 17 +- end ++ def test_update_raise_if_key_not_set ++ assert_raise(OpenSSL::Cipher::CipherError) do ++ # it caused OpenSSL SEGV by uninitialized key [Bug #2768] ++ OpenSSL::Cipher::AES128.new("ECB").update "." * 17 + end + end + end +@@ -236,6 +235,24 @@ def test_aes_gcm_wrong_ciphertext + end + end + ++ def test_aes_gcm_key_iv_order_issue ++ pt = "[ruby/openssl#49]" ++ cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt ++ cipher.key = "x" * 16 ++ cipher.iv = "a" * 12 ++ ct1 = cipher.update(pt) << cipher.final ++ tag1 = cipher.auth_tag ++ ++ cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt ++ cipher.iv = "a" * 12 ++ cipher.key = "x" * 16 ++ ct2 = cipher.update(pt) << cipher.final ++ tag2 = cipher.auth_tag ++ ++ assert_equal ct1, ct2 ++ assert_equal tag1, tag2 ++ end if has_cipher?("aes-128-gcm") ++ + end + + private diff --git a/ruby.spec b/ruby.spec index 2fd29f9..0dbc45e 100644 --- a/ruby.spec +++ b/ruby.spec @@ -21,7 +21,7 @@ %endif -%global release 61.1 +%global release 62 %{!?release_string:%global release_string %{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}} # The RubyGems library has to stay out of Ruby directory three, since the @@ -122,6 +122,10 @@ Patch6: ruby-2.1.0-Allow-to-specify-additional-preludes-by-configuratio.patch # Use miniruby to regenerate prelude.c. # https://bugs.ruby-lang.org/issues/10554 Patch7: ruby-2.2.3-Generate-preludes-using-miniruby.patch +# Fix IV Reuse in GCM Mode (CVE-2016-7798). +# https://bugzilla.redhat.com/show_bug.cgi?id=1381527 +# https://github.com/ruby/ruby/commit/739782e37a6662fea379e7ef3ec89e851b04b46c +Patch10: ruby-2.3.4-remove-the-encryption-key-initialization.patch # Do not freeze strings in generated .gemspec. This causes regressions # and FTBFS in Fedora packages. This is revert of: # https://github.com/rubygems/rubygems/commit/8eda3272d28010c768a05620de776e5a8195c1ae @@ -474,6 +478,7 @@ rm -rf ext/fiddle/libffi* %patch5 -p1 %patch6 -p1 %patch7 -p1 +%patch10 -p1 %patch100 -p1 # Provide an example of usage of the tapset: @@ -964,6 +969,9 @@ make check TESTS="-v $DISABLE_TESTS" %{ruby_libdir}/tkextlib %changelog +* Thu Jul 27 2017 Vít Ondruch - 2.3.3-62 +- Fix IV Reuse in GCM Mode (rhbz#1381527). + * Thu Dec 01 2016 Vít Ondruch - 2.3.3-61.1 - Do not freeze strings in generated .gemspec. diff --git a/sources b/sources index 26c008e..ef0a324 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -0cba3d1b677d2695236ace62ca6d2255 ruby-2.3.3.tar.xz +SHA512 (ruby-2.3.3.tar.xz) = 73dd6ed896ff52d953b153b2cab359c87953ea77521878f1ee16c1e217cc46bcb253100debe61ba631e6ffa0bc773e592d603a374508ed5189a311136ccd8d20