summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-devtools/ruby/ruby/CVE-2016-7798.patch164
-rw-r--r--meta/recipes-devtools/ruby/ruby_2.2.5.bb4
2 files changed, 167 insertions, 1 deletions
diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2016-7798.patch b/meta/recipes-devtools/ruby/ruby/CVE-2016-7798.patch
new file mode 100644
index 0000000000..2b8772ba41
--- /dev/null
+++ b/meta/recipes-devtools/ruby/ruby/CVE-2016-7798.patch
@@ -0,0 +1,164 @@
1cipher: don't set dummy encryption key in Cipher#initialize
2Remove the encryption key initialization from Cipher#initialize. This
3is effectively a revert of r32723 ("Avoid possible SEGV from AES
4encryption/decryption", 2011-07-28).
5
6r32723, which added the key initialization, was a workaround for
7Ruby Bug #2768. For some certain ciphers, calling EVP_CipherUpdate()
8before setting an encryption key caused segfault. It was not a problem
9until OpenSSL implemented GCM mode - the encryption key could be
10overridden by repeated calls of EVP_CipherInit_ex(). But, it is not the
11case for AES-GCM ciphers. Setting a key, an IV, a key, in this order
12causes the IV to be reset to an all-zero IV.
13
14The problem of Bug #2768 persists on the current versions of OpenSSL.
15So, make Cipher#update raise an exception if a key is not yet set by the
16user. Since encrypting or decrypting without key does not make any
17sense, this should not break existing applications.
18
19Users can still call Cipher#key= and Cipher#iv= multiple times with
20their own responsibility.
21
22Reference: https://bugs.ruby-lang.org/issues/2768
23Reference: https://bugs.ruby-lang.org/issues/8221
24
25Upstream-Status: Backport
26CVE: CVE-2016-7798
27
28Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com>
29
30Index: ruby-2.2.2/ext/openssl/ossl_cipher.c
31===================================================================
32--- ruby-2.2.2.orig/ext/openssl/ossl_cipher.c
33+++ ruby-2.2.2/ext/openssl/ossl_cipher.c
34@@ -35,6 +35,7 @@
35 */
36 VALUE cCipher;
37 VALUE eCipherError;
38+static ID id_key_set;
39
40 static VALUE ossl_cipher_alloc(VALUE klass);
41 static void ossl_cipher_free(void *ptr);
42@@ -119,7 +120,6 @@ ossl_cipher_initialize(VALUE self, VALUE
43 EVP_CIPHER_CTX *ctx;
44 const EVP_CIPHER *cipher;
45 char *name;
46- unsigned char key[EVP_MAX_KEY_LENGTH];
47
48 name = StringValuePtr(str);
49 GetCipherInit(self, ctx);
50@@ -131,14 +131,7 @@ ossl_cipher_initialize(VALUE self, VALUE
51 if (!(cipher = EVP_get_cipherbyname(name))) {
52 ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name);
53 }
54- /*
55- * The EVP which has EVP_CIPH_RAND_KEY flag (such as DES3) allows
56- * uninitialized key, but other EVPs (such as AES) does not allow it.
57- * Calling EVP_CipherUpdate() without initializing key causes SEGV so we
58- * set the data filled with "\0" as the key by default.
59- */
60- memset(key, 0, EVP_MAX_KEY_LENGTH);
61- if (EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, -1) != 1)
62+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
63 ossl_raise(eCipherError, NULL);
64
65 return self;
66@@ -256,6 +249,8 @@ ossl_cipher_init(int argc, VALUE *argv,
67 if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) {
68 ossl_raise(eCipherError, NULL);
69 }
70+ if (p_key)
71+ rb_ivar_set(self, id_key_set, Qtrue);
72
73 return self;
74 }
75@@ -343,6 +338,8 @@ ossl_cipher_pkcs5_keyivgen(int argc, VAL
76 OPENSSL_cleanse(key, sizeof key);
77 OPENSSL_cleanse(iv, sizeof iv);
78
79+ rb_ivar_set(self, id_key_set, Qtrue);
80+
81 return Qnil;
82 }
83
84@@ -396,6 +393,9 @@ ossl_cipher_update(int argc, VALUE *argv
85
86 rb_scan_args(argc, argv, "11", &data, &str);
87
88+ if (!RTEST(rb_attr_get(self, id_key_set)))
89+ ossl_raise(eCipherError, "key not set");
90+
91 StringValue(data);
92 in = (unsigned char *)RSTRING_PTR(data);
93 if ((in_len = RSTRING_LEN(data)) == 0)
94@@ -495,6 +495,8 @@ ossl_cipher_set_key(VALUE self, VALUE ke
95 if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
96 ossl_raise(eCipherError, NULL);
97
98+ rb_ivar_set(self, id_key_set, Qtrue);
99+
100 return key;
101 }
102
103@@ -1013,5 +1015,7 @@ Init_ossl_cipher(void)
104 rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0);
105 rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0);
106 rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
107+
108+ id_key_set = rb_intern_const("key_set");
109 }
110
111Index: ruby-2.2.2/test/openssl/test_cipher.rb
112===================================================================
113--- ruby-2.2.2.orig/test/openssl/test_cipher.rb
114+++ ruby-2.2.2/test/openssl/test_cipher.rb
115@@ -80,6 +80,7 @@ class OpenSSL::TestCipher < Test::Unit::
116
117 def test_empty_data
118 @c1.encrypt
119+ @c1.random_key
120 assert_raise(ArgumentError){ @c1.update("") }
121 end
122
123@@ -127,13 +128,10 @@ class OpenSSL::TestCipher < Test::Unit::
124 assert_equal(pt, c2.update(ct) + c2.final)
125 }
126 end
127-
128- def test_AES_crush
129- 500.times do
130- assert_nothing_raised("[Bug #2768]") do
131- # it caused OpenSSL SEGV by uninitialized key
132- OpenSSL::Cipher::AES128.new("ECB").update "." * 17
133- end
134+ def test_update_raise_if_key_not_set
135+ assert_raise(OpenSSL::Cipher::CipherError) do
136+ # it caused OpenSSL SEGV by uninitialized key [Bug #2768]
137+ OpenSSL::Cipher::AES128.new("ECB").update "." * 17
138 end
139 end
140 end
141@@ -236,6 +234,23 @@ class OpenSSL::TestCipher < Test::Unit::
142 end
143
144 end
145+ def test_aes_gcm_key_iv_order_issue
146+ pt = "[ruby/openssl#49]"
147+ cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
148+ cipher.key = "x" * 16
149+ cipher.iv = "a" * 12
150+ ct1 = cipher.update(pt) << cipher.final
151+ tag1 = cipher.auth_tag
152+
153+ cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
154+ cipher.iv = "a" * 12
155+ cipher.key = "x" * 16
156+ ct2 = cipher.update(pt) << cipher.final
157+ tag2 = cipher.auth_tag
158+
159+ assert_equal ct1, ct2
160+ assert_equal tag1, tag2
161+ end if has_cipher?("aes-128-gcm")
162
163 private
164
diff --git a/meta/recipes-devtools/ruby/ruby_2.2.5.bb b/meta/recipes-devtools/ruby/ruby_2.2.5.bb
index 66ba1d4b84..35882d18e6 100644
--- a/meta/recipes-devtools/ruby/ruby_2.2.5.bb
+++ b/meta/recipes-devtools/ruby/ruby_2.2.5.bb
@@ -3,7 +3,9 @@ require ruby.inc
3SRC_URI[md5sum] = "bd8e349d4fb2c75d90817649674f94be" 3SRC_URI[md5sum] = "bd8e349d4fb2c75d90817649674f94be"
4SRC_URI[sha256sum] = "30c4b31697a4ca4ea0c8db8ad30cf45e6690a0f09687e5d483c933c03ca335e3" 4SRC_URI[sha256sum] = "30c4b31697a4ca4ea0c8db8ad30cf45e6690a0f09687e5d483c933c03ca335e3"
5 5
6SRC_URI += "file://prevent-gc.patch" 6SRC_URI += "file://prevent-gc.patch \
7 file://CVE-2016-7798.patch \
8"
7 9
8# it's unknown to configure script, but then passed to extconf.rb 10# it's unknown to configure script, but then passed to extconf.rb
9# maybe it's not really needed as we're hardcoding the result with 11# maybe it's not really needed as we're hardcoding the result with