Date: Mon, 19 Sep 2016 15:20:02 -0400 From: Mike Santillana <michael.santillana@...ork.com> To: oss-security@...ts.openwall.com Cc: "'Apple' via" <infosec@...ork.com> Subject: CVE Request - Ruby OpenSSL Library - IV Reuse in GCM Mode Product: Ruby's OpenSSL Library Version: Tested on 2.3.1 (latest) Bug: IV Reuse Impact: Depends on the usage of the library Hello, An IV reuse bug was discovered in Ruby's OpenSSL library when using aes-gcm. When encrypting data with aes-*-gcm, if the IV is set before setting the key, the cipher will default to using a static IV. This creates a static nonce and since aes-gcm is a stream cipher, this can lead to known cryptographic issues. The documentation does not appear to specify the order of operations when setting the key and IV [1]. As an example, see the following insecure code snippet below: Vulnerable Code: def encrypt(plaintext) cipher = OpenSSL::Cipher.new('aes-256-gcm') iv = cipher.random_iv # Notice here the IV is set before the key cipher.key = '11111111111111111111111111111111' cipher.auth_data = "" ciphertext = cipher.update(plaintext) + cipher.final tag = cipher.auth_tag puts "[+] Encrypting: #{plaintext}" puts "[+] CipherMessage (IV | Tag | Ciphertext): #{bin2hex(iv)} | #{bin2hex(tag)} | #{bin2hex(ciphertext)}" end A developer that uses the code above may incorrectly assume that their code is secure from the pitfalls associated with IV reuse in aes-*-gcm, since the ‘cipher.random_iv’ method is used. According to the documentation, this should generate a random IV each time the encryption method is called. When the code above is run with the same key and same plaintext message, the following results are obtained: Output: # Run 1 ./gcm_encrypt.rb 'This is some secret message.' [+] Encrypting: This is some secret message. [+] CipherMessage (IV | Tag | Ciphertext): e32594080cca2b37f7d7e968 | 8c676db7551cf046266252ee776ecaa9 | 81092d16b62902d9985656253891dc 800a5bb48fb1c4ad0b7bdf6054 # Run 2 ./gcm_encrypt.rb 'This is some secret message.' [+] Encrypting: This is some secret message. [+] CipherMessage (IV | Tag | Ciphertext): 431d70714f5e5f876d1c7830 | 8c676db7551cf046266252ee776ecaa9 | 81092d16b62902d9985656253891dc 800a5bb48fb1c4ad0b7bdf6054 Notice that in the output above a unique IV is returned for both runs, but with the same ciphertext. This proves that even though the random_iv method is called, the code is defaulting to a static IV. If an attacker can retrieve multiple ciphertext messages, it is possible to decrypt the ciphertexts by applying the same attack one would use in a two-time pad (XOR ciphertexts and crib drag). Next review the following code snippet and output, which depicts a secure implementation of the code: Valid Code: def encrypt(plaintext) cipher = OpenSSL::Cipher.new('aes-256-gcm') cipher.key = '11111111111111111111111111111111' iv = cipher.random_iv # Notice here the IV is set after the key cipher.auth_data = "" ciphertext = cipher.update(plaintext) + cipher.final tag = cipher.auth_tag puts "[+] Encrypting: #{plaintext}" puts "[+] CipherMessage (IV | Tag | Ciphertext): #{bin2hex(iv)} | #{bin2hex(tag)} | #{bin2hex(ciphertext)}" end Output: # Run 1 ./gcm_encrypt.rb 'This is some secret message.' [+] Encrypting: This is some secret message. [+] CipherMessage (IV | Tag | Ciphertext): 8beb4aa05533e90f4f4eddd3 | ea1b015958a9b8bd2aafa61887309caf | 19574a9c9869b92140a57a5fd43a14 9a5eaa7e5beefdff5d56cc4136 # Run 2 ./gcm_encrypt.rb 'This is some secret message.' [+] Encrypting: This is some secret message. [+] CipherMessage (IV | Tag | Ciphertext): 87361b3f1e32291602ac7b40 | bce7093daa10cc9d2fad0f2b91e077f2 | 47f9a5ba55631204233ace70f169e6 65846e877dca11a6e13a659540 Notice that this time both the IV and ciphertexts are both different for the same plaintext. This is the intended result a developer would expect to happen when using this library. It should be noted that when I went to Ruby's github page to report this bug, I noticed a developer also independently encountered this weird phenomenon [2]. Since it has already been brought up to the Ruby team, I have not created a new ticket. References: [1] https://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html#class-OpenSSL::Cipher-label-Authenticated+Encryption+and+Associated+Data+-28AEAD-29 [2] https://github.com/ruby/openssl/issues/49 I'd like to to request a CVE ID for this issue. Thanks *WeWork | Mike Santillana* Security Engineer 845-709-5655 www.wework.com Create Your Life's Work

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.